{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "uudYItMGJel0"
   },
   "source": [
    "# Install Library\n",
    "\n",
    "[RDKit ](https://github.com/rdkit/rdkit)\n",
    "\n",
    "[DGL](https://github.com/dmlc/dgl/)\n",
    "\n",
    "[DGL-LifeSci](https://github.com/awslabs/dgl-lifesci)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "IYZ1ollGWzma",
    "outputId": "2783c8df-d3b8-4606-9611-7ee6e9407627"
   },
   "outputs": [],
   "source": [
    "!pip install --pre dgl -f https://data.dgl.ai/wheels/cu113/repo.html\n",
    "!pip install --pre dglgo -f https://data.dgl.ai/wheels-test/repo.html"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "271tuyJSQ-m3"
   },
   "outputs": [],
   "source": [
    "%%capture\n",
    "!pip install rdkit-pypi\n",
    "!pip install dgllife"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true,
    "id": "il7EqGqbY5pK"
   },
   "source": [
    "# Import Library"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.environ['PYTHONHASHSEED'] = '0'\n",
    "os.environ['CUDA_VISIBLE_DEVICES']='-1'\n",
    "os.environ['TF_CUDNN_USE_AUTOTUNE'] ='0'\n",
    "\n",
    "import dgl \n",
    "import sys\n",
    "import random\n",
    "import statistics\n",
    "import cv2\n",
    "import torchvision\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import torch.nn as nn\n",
    "import matplotlib.pyplot as plt\n",
    "import torch.optim as optim\n",
    "\n",
    "from numpy import array\n",
    "from numpy import argmax\n",
    "from tensorflow.keras.utils import to_categorical\n",
    "from dgllife.utils import smiles_to_bigraph, CanonicalAtomFeaturizer, AttentiveFPAtomFeaturizer\n",
    "from tqdm.notebook import tqdm, trange\n",
    "from sklearn.model_selection import train_test_split\n",
    "from dgllife.model import MLPPredictor\n",
    "\n",
    "from utils.general import DATASET, get_dataset, separate_active_and_inactive_data, get_embedding_vector_class, count_lablel,data_generator\n",
    "from utils.gcn_pre_trained import get_muv_model\n",
    "from model.heterogeneous_siamese_muv import siamese_model_attentiveFp_muv, siamese_model_Canonical_muv\n",
    "\n",
    "random.seed(1)\n",
    "np.random.seed(1)\n",
    "tf.random.set_seed(1)\n",
    "\n",
    "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true,
    "id": "1RVgRpTmQ5rp"
   },
   "source": [
    "# Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "hidden": true,
    "id": "VunMwXfRM09K",
    "outputId": "66c67adf-0024-4585-81a1-897e7ad4638c"
   },
   "outputs": [],
   "source": [
    "cache_path='./muv_dglgraph.bin'\n",
    "\n",
    "df = get_dataset(\"muv\")\n",
    "\n",
    "ids = df['mol_id'].tolist()\n",
    "load_full = False\n",
    "\n",
    "df = df.drop(columns=['mol_id'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "hidden": true,
    "id": "rY_JnWz5M6bU"
   },
   "outputs": [],
   "source": [
    "muv_tasks = df.columns.values[:17].tolist()\n",
    "muv_tasks_test = muv_tasks[12:17]\n",
    "train_task, valid_task = train_test_split(muv_tasks, test_size=0.25 , shuffle= False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "hidden": true,
    "id": "HO5RmBnZM8mq",
    "outputId": "4b0ad369-893f-4246-bbdf-4257b3016f35"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MUV-466 one: 27  zero: 78246  NAN: 14814\n",
      "MUV-548 one: 29  zero: 78353  NAN: 14705\n",
      "MUV-600 one: 30  zero: 78359  NAN: 14698\n",
      "MUV-644 one: 30  zero: 78464  NAN: 14593\n",
      "MUV-652 one: 29  zero: 78185  NAN: 14873\n",
      "MUV-689 one: 29  zero: 78486  NAN: 14572\n",
      "MUV-692 one: 30  zero: 78443  NAN: 14614\n",
      "MUV-712 one: 28  zero: 78676  NAN: 14383\n",
      "MUV-713 one: 29  zero: 78251  NAN: 14807\n",
      "MUV-733 one: 28  zero: 78405  NAN: 14654\n",
      "MUV-737 one: 29  zero: 78396  NAN: 14662\n",
      "MUV-810 one: 29  zero: 78443  NAN: 14615\n",
      "MUV-832 one: 30  zero: 78420  NAN: 14637\n",
      "MUV-846 one: 30  zero: 78376  NAN: 14681\n",
      "MUV-852 one: 29  zero: 78436  NAN: 14622\n",
      "MUV-858 one: 29  zero: 78313  NAN: 14745\n",
      "MUV-859 one: 24  zero: 78341  NAN: 14722\n"
     ]
    }
   ],
   "source": [
    "one = []\n",
    "zero = []\n",
    "nan = []\n",
    " \n",
    "for task in muv_tasks:\n",
    "    a = list(df[task].value_counts(dropna=False).to_dict().values())\n",
    "    zero.append(a[0])\n",
    "    nan.append(a[1])\n",
    "    one.append(a[2])\n",
    "    print(task ,\"one:\" ,a[2] ,\" zero:\", a[0], \" NAN:\",a[1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 894
    },
    "hidden": true,
    "id": "ZZcv6iPNNS19",
    "outputId": "6c6f9597-0181-4b83-8e31-943902aedb01"
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABmsAAATWCAYAAADKEZL3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAACNVElEQVR4nOz9e5jVdb3//z9GziCMIMJInsiQRDRNTVELTAVT0M+28gBS5CGNkk2Jmnu7C63wgJIlZe7CYxi2M9uWSZilbfJMYeIhKxEwQTyMM4oIiOv7hz/XrxFUwIUvldvtutZ1Ne/1Wu/3az2dusbu13utukqlUgkAAAAAAABFbFR6AwAAAAAAABsysQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAADYwl19+eerq6lJXV5dbbrlllecrlUo+8IEPpK6uLoMGDaoef/TRR1NXV5fzzz9/tec9//zzU1dXl0cffTRPPvlk2rZtmyOPPPJ199Hc3JyOHTvmkEMOWev3cMstt7zu/t/MbbfdlvHjx+fZZ59d69euD7/+9a8zfvz4t3yeQYMGrfaf1+WXX/6Wzw0AAKxfYg0AAGygOnfunClTpqxy/NZbb80//vGPdO7ceZ3Pvdlmm+WQQw7JL37xizQ2Nq52zbRp07J06dIce+yx63yddXHbbbflzDPPfEfFmjPPPLPm5918881z++235+CDD675uQEAgNoSawAAYAN1xBFH5Nprr01zc3OL41OmTMmAAQOy1VZbvaXzH3vssVm2bFmmTp262ucvvfTS9OzZU0xYT9q1a5c999wzm2222dt+7RdeeOFtvyYAALybiTUAALCBOuqoo5IkP/nJT6rHmpqacu211+aYY455y+cfMmRItthii1x22WWrPPfggw/mzjvvzGc+85m0bt36Dc/z0EMP5cADD0zHjh3TvXv3nHjiiXnuuedWWXfTTTfl0EMPzRZbbJH27dvnAx/4QE444YQ89dRT1TXjx4/PKaeckiTp3bv3Kh8Hd80112Tw4MHZfPPN06FDh2y//fb56le/miVLlrS41iOPPJIjjzwyvXr1Srt27dKzZ8/st99+mT17dot111xzTQYMGJBOnTpl4403zpAhQ/LnP/+5+vyoUaPyve99L0mqe3n1o+ReT6VSyXnnnZett9467du3z4c//OHceOONq6xb3ceg/f3vf8/nPve59OnTJx07dsz73ve+DBs2LPfdd98qr7///vszePDgdOzYMZtttlm++MUv5oYbbljl4+cGDRqU/v375w9/+EP22muvdOzYsfr7s6bzHDVqVDbeeOM89NBDGTJkSDp16pTNN98855xzTpLkjjvuyD777JNOnTplu+22yxVXXPG68wEAgHejN/63IgAA4D2rS5cu+dSnPpVLL700J5xwQpJXws1GG22UI444IhdeeOFbOv9GG22UUaNG5Zvf/GbuvffefOhDH6o+92rAebMo9MQTT2TgwIFp06ZNvv/976dnz56ZOnVqvvSlL62y9h//+EcGDBiQ4447LvX19Xn00UczadKk7LPPPrnvvvvSpk2bHHfccXnmmWdy0UUX5ec//3k233zzJEm/fv2SJH/7299y0EEHZezYsenUqVMeeuihnHvuubnrrrvyu9/9rnqtgw46KCtXrsx5552XrbbaKk899VRuu+22Fh+tNmHChJxxxhn53Oc+lzPOOCPLly/PxIkT89GPfjR33XVX+vXrl//6r//KkiVL8rOf/Sy333579bWv7mt1zjzzzJx55pk59thj86lPfSoLFizI8ccfn5UrV6Zv375vOM/HH388m266ac4555xsttlmeeaZZ3LFFVdkjz32yJ///Ofq6xcuXJiBAwemU6dOufjii9OjR4/85Cc/We3cX11/9NFH59RTT82ECROy0UYbrdU8k2TFihU57LDDcuKJJ+aUU07J1VdfndNPPz3Nzc259tprc9ppp2WLLbbIRRddlFGjRqV///7Zdddd3/D9AgDAu0YFAADYoFx22WWVJJW777678vvf/76SpDJnzpxKpVKp7L777pVRo0ZVKpVKZYcddqgMHDiw+rq5c+dWklQmTpy42vNOnDixkqQyd+7c6rFHHnmkUldXVxkzZkz12IoVKyoNDQ2Vvffe+033etppp1Xq6uoqs2fPbnH8gAMOqCSp/P73v1/t615++eXKihUrKvPmzaskqfzv//7vG+7zjc5x6623VpJU7r333kqlUqk89dRTlSSVCy+88HVfO3/+/Err1q0rJ510Uovjzz33XKWhoaFy+OGHV4998YtfrKzpv5o1NjZW2rdvX/m3f/u3Fsf/+Mc/VpKs9p/XZZdd9rrne+mllyrLly+v9OnTp/LlL3+5evyUU06p1NXVVe6///4W64cMGbLK3AcOHFhJUrn55pvfcO+vN89KpVL57Gc/W0lSufbaa6vHVqxYUdlss80qSSp/+tOfqseffvrpSqtWrSpf+cpX3vB6AADwbuJj0AAAYAM2cODAbLvttrn00ktz33335e67767JR6C9qnfv3tl3330zderULF++PEly4403ZtGiRWt0nd///vfZYYcdWtyVkyTDhw9fZe3ixYtz4oknZsstt0zr1q3Tpk2bbL311kle+di1NfHII49k+PDhaWhoSKtWrdKmTZsMHDiwxTm6deuWbbfdNhMnTsykSZPy5z//OS+//HKL8/zmN7/JSy+9lM985jN56aWXqo/27dtn4MCBLT5GbG3cfvvtefHFFzNixIgWx/faa6/qe30jL730UiZMmJB+/fqlbdu2ad26ddq2bZu//e1vLWZ06623pn///tU7jl716kfnvVbXrl3z8Y9/fJXjazLPV9XV1eWggw6q/ty6det84AMfyOabb55ddtmlerxbt27p0aNH5s2b96bvFwAA3i18DBoAAGzA6urq8rnPfS7f/e538+KLL2a77bbLRz/60dWuffW7ZVauXLna51966aUkSZs2bVocP/bYYzNixIhcf/31+dSnPpXLLrssG2+8cQ4//PA33d/TTz+d3r17r3K8oaGhxc8vv/xyBg8enMcffzz/9V//lR133DGdOnXKyy+/nD333DNLly5902s9//zz+ehHP5r27dvnm9/8Zrbbbrt07NgxCxYsyGGHHVY9R11dXW6++eacddZZOe+883LyySenW7duGTFiRL71rW+lc+fOeeKJJ5Iku++++2qv9erHhK2tp59+erXv//WOvdZXvvKVfO9738tpp52WgQMHpmvXrtloo41y3HHHtZjR6829Z8+eqz3v6j62bU3n+aqOHTumffv2LY61bds23bp1W+Xcbdu2zYsvvvim7xcAAN4txBoAANjAjRo1Kl/72tfygx/8IN/61rded1337t3TqlWr/POf/1zt8//85z/TqlWrbLrppi2OH3bYYenatWsuvfTSDBw4ML/61a/ymc98JhtvvPGb7m3TTTfNokWLVjn+2mNz5szJvffem8svvzyf/exnq8f//ve/v+k1XvW73/0ujz/+eG655Zbq3R9JWnwPzau23nrrTJkyJUny8MMP56c//WnGjx+f5cuX5wc/+EG6d++eJPnZz362Rne8rKlXZ/t6M9lmm23e8PU//vGP85nPfCYTJkxocfypp57KJpts0uI6rwan115jderq6lY5tjbzBACADZ2PQQMAgA3c+973vpxyyikZNmxYi9DxWu3bt8/ee++d66+/fpW7Gl588cVcf/312WeffVa5O6J9+/YZPnx4ZsyYkXPPPTcrVqxY449a23fffXP//ffn3nvvbXH86quvbvHzq7GgXbt2LY5fcsklq5zz1TWvvbNjbc7xr7bbbrucccYZ2XHHHfOnP/0pSTJkyJC0bt06//jHP7Lbbrut9vFm+1mdPffcM+3bt8/UqVNbHL/tttvW6GPB6urqVnl/N9xwwyoBbuDAgZkzZ04eeOCBFsenTZv2ptf412slaz9PAADYELmzBgAAyDnnnLPG6/bdd98MGDAgY8eOzVZbbZX58+fnwgsvzBNPPPG6/2f+sccem+9973uZNGlSPvjBD2avvfZao+uNHTs2l156aQ4++OB885vfTM+ePTN16tQ89NBDLdZ98IMfzLbbbpuvfvWrqVQq6datW375y1/mpptuWuWcO+64Y5LkO9/5Tj772c+mTZs26du3b/baa6907do1J554Yr7+9a+nTZs2mTp16iqh6C9/+Uu+9KUv5dOf/nT69OmTtm3b5ne/+13+8pe/5Ktf/WqSZJtttslZZ52V//zP/8wjjzySAw88MF27ds0TTzyRu+66K506dcqZZ57ZYj/nnntuPvGJT6RVq1bZaaed0rZt21X23rVr14wbNy7f/OY3c9xxx+XTn/50FixYkPHjx6/Rx6ANHTo0l19+eT74wQ9mp512yqxZszJx4sRsscUWq537Jz7xiZx11lnp2bNnrr766urc1+Rj3NZ0ngAAgDtrAACAtTBgwID88Y9/TO/evTNu3LgccMABGTduXHr37p3bbrstAwYMWO3rdtlll+yyyy6pVCprfFdN8sr3sNx6663p169fvvCFL+Too49O+/btM3ny5Bbr2rRpk1/+8pfZbrvtcsIJJ+Soo47K4sWL89vf/naVcw4aNCinn356fvnLX2afffbJ7rvvnlmzZmXTTTfNDTfckI4dO+boo4/OMccck4033jjXXHPNKnvadttt8/3vfz+f+tSncuihh+aXv/xlLrjggpx11lnVdaeffnp+9rOf5eGHH85nP/vZDBkyJKeeemrmzZuXj33sY9V1w4cPz3HHHZfvf//7GTBgQHbfffc8/vjjrzuTs846K2effXZmzJiRQw45JBdddFF+8IMfpG/fvm86z+985zs5+uijc/bZZ2fYsGG5/vrr8/Of/zzbbrtti3W9evXKrbfemu222y4nnnhiRowYkbZt21bf379+ZNrrWdN5AgAASV2lUqmU3gQAAADvfJ///Ofzk5/8JE8//fRq7/wBAADWjY9BAwAAYBVnnXVWevXqlfe///15/vnn86tf/So/+tGPcsYZZwg1AABQY2INAAAAq2jTpk0mTpyYxx57LC+99FL69OmTSZMm5d///d9Lbw0AAN5zfAwaAAAAAABAQRuV3gAAAAAAAMCGTKwBAAAAAAAoSKwBAAAAAAAoqHXpDbyXvPzyy3n88cfTuXPn1NXVld4OAAAAAABQUKVSyXPPPZdevXplo41e//4ZsaaGHn/88Wy55ZaltwEAAAAAALyDLFiwIFtsscXrPi/W1FDnzp2TvDL0Ll26FN4NAAAAAABQUnNzc7bccstqP3g9Yk0NvfrRZ126dBFrAAAAAACAJHnTr055/Q9IAwAAAAAAYL0TawAAAAAAAAoSawAAAAAAAArynTUAAAAAAPAOt3LlyqxYsaL0NniNVq1apXXr1m/6nTRvRqwBAAAAAIB3sOeffz6PPfZYKpVK6a2wGh07dszmm2+etm3brvM5xBoAAAAAAHiHWrlyZR577LF07Ngxm2222Vu+g4PaqVQqWb58eZ588snMnTs3ffr0yUYbrdu3z4g1AAAAAADwDrVixYpUKpVsttlm6dChQ+nt8BodOnRImzZtMm/evCxfvjzt27dfp/OsW+IBAAAAAADeNu6oeeda17tpWpyjBvsAAAAAAABgHYk1AAAAAAAABfnOGgAAAAAAeJepO/Pt/Vi0ytcrb+v1Vufyyy/P2LFj8+yzz5beSs25swYAAAAAAFgvbrvttrRq1SoHHnjgWr1um222yYUXXtji2BFHHJGHH364hrt75xBrAAAAAACA9eLSSy/NSSedlJkzZ2b+/Plv6VwdOnRIjx49arSzdxaxBgAAAAAAqLklS5bkpz/9ab7whS9k6NChufzyy1s8f/3112e33XZL+/bt07179xx22GFJkkGDBmXevHn58pe/nLq6utTVvfKRb5dffnk22WSTJMlf//rX1NXV5aGHHmpxzkmTJmWbbbZJpfLKx7Y98MADOeigg7LxxhunZ8+eGTlyZJ566qn1+8bXgVgDAAAAAADU3DXXXJO+ffumb9++Ofroo3PZZZdVI8oNN9yQww47LAcffHD+/Oc/5+abb85uu+2WJPn5z3+eLbbYImeddVYWLlyYhQsXrnLuvn37Ztddd83UqVNbHL/66qszfPjw1NXVZeHChRk4cGB23nnn3HPPPZk+fXqeeOKJHH744ev/za+l1qU3AAAAAAAAvPdMmTIlRx99dJLkwAMPzPPPP5+bb745+++/f771rW/lyCOPzJlnnlld/6EPfShJ0q1bt7Rq1SqdO3dOQ0PD655/xIgRmTx5cr7xjW8kSR5++OHMmjUrV155ZZLk4osvzoc//OFMmDCh+ppLL700W265ZR5++OFst912NX/P68qdNQAAAAAAQE399a9/zV133ZUjjzwySdK6descccQRufTSS5Mks2fPzn777feWrnHkkUdm3rx5ueOOO5IkU6dOzc4775x+/folSWbNmpXf//732XjjjauPD37wg0mSf/zjH2/p2rXmzhoAAAAAAKCmpkyZkpdeeinve9/7qscqlUratGmTxsbGdOjQ4S1fY/PNN8++++6bq6++OnvuuWd+8pOf5IQTTqg+//LLL2fYsGE599xzV/vadxKxBgAAAAAAqJmXXnopV155ZS644IIMHjy4xXOf/OQnM3Xq1Oy00065+eab87nPfW6152jbtm1Wrlz5ptcaMWJETjvttBx11FH5xz/+Ub2TJ0k+/OEP59prr80222yT1q3f2TnEx6ABAAAAAAA186tf/SqNjY059thj079//xaPT33qU5kyZUq+/vWv5yc/+Um+/vWv58EHH8x9992X8847r3qObbbZJn/4wx/yz3/+M0899dTrXuuwww5Lc3NzvvCFL2TfffdtcSfPF7/4xTzzzDM56qijctddd+WRRx7JjBkzcswxx6xRCHo7vbNTEgAAAAAAsIrK1yult/C6pkyZkv333z/19fWrPPfJT34yEyZMSJcuXfI///M/+cY3vpFzzjknXbp0ycc+9rHqurPOOisnnHBCtt122yxbtiyVyurfb5cuXTJs2LD8z//8T/X7cF7Vq1ev/PGPf8xpp52WIUOGZNmyZdl6661z4IEHZqON3ln3stRVXu8dstaam5tTX1+fpqamdOnSpfR2AAAAAAB4l3vxxRczd+7c9O7dO+3bty+9HVbjjf4ZrWk3eGelIwAAAAAAgA2MWAMAAAAAAFCQWAMAAAAAAFCQWAMAAAAAAFCQWAMAAAAAAFCQWAMAAAAAAFCQWAMAAAAAAFBQ0Vjz0ksv5Ywzzkjv3r3ToUOHvP/9789ZZ52Vl19+ubqmUqlk/Pjx6dWrVzp06JBBgwbl/vvvb3GeZcuW5aSTTkr37t3TqVOnHHLIIXnsscdarGlsbMzIkSNTX1+f+vr6jBw5Ms8++2yLNfPnz8+wYcPSqVOndO/ePWPGjMny5cvX2/sHAAAAAAAoGmvOPffc/OAHP8jkyZPz4IMP5rzzzsvEiRNz0UUXVdecd955mTRpUiZPnpy77747DQ0NOeCAA/Lcc89V14wdOzbXXXddpk2blpkzZ+b555/P0KFDs3Llyuqa4cOHZ/bs2Zk+fXqmT5+e2bNnZ+TIkdXnV65cmYMPPjhLlizJzJkzM23atFx77bU5+eST355hAAAAAAAAG6S6SqVSKXXxoUOHpmfPnpkyZUr12Cc/+cl07NgxV111VSqVSnr16pWxY8fmtNNOS/LKXTQ9e/bMueeemxNOOCFNTU3ZbLPNctVVV+WII45Ikjz++OPZcsst8+tf/zpDhgzJgw8+mH79+uWOO+7IHnvskSS54447MmDAgDz00EPp27dvbrzxxgwdOjQLFixIr169kiTTpk3LqFGjsnjx4nTp0uVN309zc3Pq6+vT1NS0RusBAAAAAOCNvPjii5k7d2569+6d9u3bV4/X1b29+yhXEtbdLbfckn333TeNjY3ZZJNN1tt1Xu+fUbLm3aDonTX77LNPbr755jz88MNJknvvvTczZ87MQQcdlCSZO3duFi1alMGDB1df065duwwcODC33XZbkmTWrFlZsWJFizW9evVK//79q2tuv/321NfXV0NNkuy5556pr69vsaZ///7VUJMkQ4YMybJlyzJr1qzV7n/ZsmVpbm5u8QAAAAAAgA3dqFGj8v/+3/972643aNCgjB07tsWxvfbaKwsXLkx9ff3bto911brkxU877bQ0NTXlgx/8YFq1apWVK1fmW9/6Vo466qgkyaJFi5IkPXv2bPG6nj17Zt68edU1bdu2TdeuXVdZ8+rrFy1alB49eqxy/R49erRY89rrdO3aNW3btq2uea2zzz47Z5555tq+bQAAAAAAYD1r27ZtGhoaSm9jjRS9s+aaa67Jj3/841x99dX505/+lCuuuCLnn39+rrjiihbr6l5zP1elUlnl2Gu9ds3q1q/Lmn91+umnp6mpqfpYsGDBG+4JAAAAAAA2NIMGDcqYMWNy6qmnplu3bmloaMj48eNbrJk0aVJ23HHHdOrUKVtuuWVGjx6d559/vsWaP/7xjxk4cGA6duyYrl27ZsiQIWlsbMyoUaNy66235jvf+U7q6upSV1eXRx99NLfcckvq6ury7LPPpqmpKR06dMj06dNbnPPnP/95OnXqVL3WP//5zxxxxBHp2rVrNt100xx66KF59NFH1+d4khSONaecckq++tWv5sgjj8yOO+6YkSNH5stf/nLOPvvsJKkWr9fe2bJ48eLqXTANDQ1Zvnx5Ghsb33DNE088scr1n3zyyRZrXnudxsbGrFixYpU7bl7Vrl27dOnSpcUDAAAAAABo6YorrkinTp1y55135rzzzstZZ52Vm266qfr8RhttlO9+97uZM2dOrrjiivzud7/LqaeeWn1+9uzZ2W+//bLDDjvk9ttvz8yZMzNs2LCsXLky3/nOdzJgwIAcf/zxWbhwYRYuXJgtt9yyxfXr6+tz8MEHZ+rUqS2OX3311Tn00EOz8cYb54UXXsi+++6bjTfeOH/4wx8yc+bMbLzxxjnwwAOzfPny9TqforHmhRdeyEYbtdxCq1at8vLLLydJevfunYaGhhb/wJYvX55bb701e+21V5Jk1113TZs2bVqsWbhwYebMmVNdM2DAgDQ1NeWuu+6qrrnzzjvT1NTUYs2cOXOycOHC6poZM2akXbt22XXXXWv8zgEAAAAAYMOx00475etf/3r69OmTz3zmM9ltt91y8803V58fO3Zs9t133/Tu3Tsf//jH841vfCM//elPq8+fd9552W233fL9738/H/rQh7LDDjvkS1/6Urp37576+vq0bds2HTt2TENDQxoaGtKqVatV9jBixIj84he/yAsvvJAkaW5uzg033JCjjz46STJt2rRstNFG+dGPfpQdd9wx22+/fS677LLMnz8/t9xyy3qdT9HvrBk2bFi+9a1vZauttsoOO+yQP//5z5k0aVKOOeaYJK98LNnYsWMzYcKE9OnTJ3369MmECRPSsWPHDB8+PMkrNezYY4/NySefnE033TTdunXLuHHjsuOOO2b//fdPkmy//fY58MADc/zxx+eSSy5Jknz+85/P0KFD07dv3yTJ4MGD069fv4wcOTITJ07MM888k3HjxuX44493xwwAAAAAALwFO+20U4ufN9988yxevLj68+9///tMmDAhDzzwQJqbm/PSSy/lxRdfzJIlS9KpU6fMnj07n/70p9/SHg4++OC0bt06119/fY488shce+216dy5cwYPHpwkmTVrVv7+97+nc+fOLV734osv5h//+MdbuvabKRprLrroovzXf/1XRo8encWLF6dXr1454YQT8rWvfa265tRTT83SpUszevToNDY2Zo899siMGTNaDOvb3/52WrduncMPPzxLly7Nfvvtl8svv7xFOZs6dWrGjBlTHfohhxySyZMnV59v1apVbrjhhowePTp77713OnTokOHDh+f8889/GyYBAAAAAADvXW3atGnxc11dXfVTtubNm5eDDjooJ554Yr7xjW+kW7dumTlzZo499tisWLEiSdKhQ4e3vIe2bdvmU5/6VK6++uoceeSRufrqq3PEEUekdetXUsnLL7+cXXfddZWPSkuSzTbb7C1f/40UjTWdO3fOhRdemAsvvPB119TV1WX8+PGrfNnQv2rfvn0uuuiiXHTRRa+7plu3bvnxj3/8hvvZaqut8qtf/erNtg0AAAAAANTIPffck5deeikXXHBB9atT/vUj0JJX7sy5+eabc+aZZ672HG3bts3KlSvf9FojRozI4MGDc//99+f3v/99vvGNb1Sf+/CHP5xrrrkmPXr0eNs/cavod9YAAAAAAAAbtm233TYvvfRSLrroojzyyCO56qqr8oMf/KDFmtNPPz133313Ro8enb/85S956KGHcvHFF+epp55KkmyzzTa588478+ijj+app56q3rXzWgMHDkzPnj0zYsSIbLPNNtlzzz2rz40YMSLdu3fPoYcemv/7v//L3Llzc+utt+bf//3f89hjj62/AUSsAQAAAACAd51K5e19rE8777xzJk2alHPPPTf9+/fP1KlTc/bZZ7dYs91222XGjBm5995785GPfCQDBgzI//7v/1Y/wmzcuHFp1apV+vXrl8022yzz589f7bXq6upy1FFH5d57782IESNaPNexY8f84Q9/yFZbbZXDDjss22+/fY455pgsXbp0vd9pU1eprO8xbziam5tTX1+fpqamt/0WKQAAAAAA3ntefPHFzJ07N71790779u1Lb4fVeKN/RmvaDdxZAwAAAAAAUJBYAwAAAAAAUJBYAwAAAAAAUJBYAwAAAAAAUJBYAwAAAAAAUJBYAwAAAAAAUJBYAwAAAAAAUJBYAwAAAAAAUJBYAwAAAAAAUFDr0hsAAADWj7q69XPeSmX9nBcAAFgL6+sP/tfjXwTWK3fWAAAAAAAANTVq1KjU1dXlnHPOaXH8F7/4RepWE5r69u2btm3b5p///Ocqzw0aNCh1dXWZNm1ai+MXXnhhttlmm5ruuxSxBgBgHdXV1f4BAAAA7xXt27fPueeem8bGxjdcN3PmzLz44ov59Kc/ncsvv/x1z3XGGWdkxYoV62Gn5Yk1ALxj+T/CYcPjv/ew4fHf+9oyz9oz09ozU97p/I5C7ey///5paGjI2Wef/YbrpkyZkuHDh2fkyJG59NJLU1nNR64dddRRaWpqyg9/+MP1td2ixBrYgPnjo7bMEwAAgLebfxeFDc8997zyeDdo1apVJkyYkIsuuiiPPfbYatc899xz+Z//+Z8cffTROeCAA7JkyZLccsstq6zr0qVL/uM//iNnnXVWlixZsp53/vYTawAAAAAAWC/WR1AUFd9d/u3f/i0777xzvv71r6/2+WnTpqVPnz7ZYYcd0qpVqxx55JGZMmXKateOHj067du3z6RJk9bnlosQa3jX8D/qAG+d/y0FeGv87ygAAKy9c889N1dccUUeeOCBVZ6bMmVKjj766OrPRx99dH7+85/n2WefXWVtu3btctZZZ2XixIl56qmn1ueW33ZiDQAAAAAAsN587GMfy5AhQ/If//EfLY4/8MADufPOO3PqqaemdevWad26dfbcc88sXbo0P/nJT1Z7rqOPPjrbbLNNvvnNb74dW3/btC69AQAAAAAA4L3tnHPOyc4775ztttuuemzKlCn52Mc+lu9973st1l511VWZMmVKvvCFL6xyno022ihnn312DjvssNU+/27lzhoAAAAAAGC92nHHHTNixIhcdNFFSZIVK1bkqquuylFHHZX+/fu3eBx33HGZNWtW7r333tWe6+CDD84ee+yRSy655O18C+uVO2sAAAAAAOBd5p67KzU712671exUb+gb3/hGfvrTnyZJrr/++jz99NP5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BYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABYk1AAAAAAAABRWPNf/85z9z9NFHZ9NNN03Hjh2z8847Z9asWdXnK5VKxo8fn169eqVDhw4ZNGhQ7r///hbnWLZsWU466aR07949nTp1yiGHHJLHHnusxZrGxsaMHDky9fX1qa+vz8iRI/Pss8+2WDN//vwMGzYsnTp1Svfu3TNmzJgsX758vb13AAAAAACAorGmsbExe++9d9q0aZMbb7wxDzzwQC644IJssskm1TXnnXdeJk2alMmTJ+fuu+9OQ0NDDjjggDz33HPVNWPHjs11112XadOmZebMmXn++eczdOjQrFy5srpm+PDhmT17dqZPn57p06dn9uzZGTlyZPX5lStX5uCDD86SJUsyc+bMTJs2Lddee21OPvnkt2UWAAAAAADAhqmuUqlUSl38q1/9av74xz/m//7v/1b7fKVSSa9evTJ27NicdtppSV65i6Znz54599xzc8IJJ6SpqSmbbbZZrrrqqhxxxBFJkscffzxbbrllfv3rX2fIkCF58MEH069fv9xxxx3ZY489kiR33HFHBgwYkIceeih9+/bNjTfemKFDh2bBggXp1atXkmTatGkZNWpUFi9enC5durzp+2lubk59fX2amprWaD1rp66u9ucs99v/zmCmtWWetWemtWemtWWetWemtbU+5pmYaa1tyPNMzLTWzLP2zLT2zLS2zLP2zLS2/E1ae35H313WtBsUvbPm+uuvz2677ZZPf/rT6dGjR3bZZZf88Ic/rD4/d+7cLFq0KIMHD64ea9euXQYOHJjbbrstSTJr1qysWLGixZpevXqlf//+1TW333576uvrq6EmSfbcc8/U19e3WNO/f/9qqEmSIUOGZNmyZS0+lu1fLVu2LM3NzS0eAAAAAAAAa6NorHnkkUdy8cUXp0+fPvnNb36TE088MWPGjMmVV16ZJFm0aFGSpGfPni1e17Nnz+pzixYtStu2bdO1a9c3XNOjR49Vrt+jR48Wa157na5du6Zt27bVNa919tlnV78Dp76+PltuueXajgAAAAAAANjAFY01L7/8cj784Q9nwoQJ2WWXXXLCCSfk+OOPz8UXX9xiXd1r7uuqVCqrHHut165Z3fp1WfOvTj/99DQ1NVUfCxYseMM9AQAAAAAAvFbRWLP55punX79+LY5tv/32mT9/fpKkoaEhSVa5s2Xx4sXVu2AaGhqyfPnyNDY2vuGaJ554YpXrP/nkky3WvPY6jY2NWbFixSp33LyqXbt26dKlS4sHAAAAAADA2igaa/bee+/89a9/bXHs4YcfztZbb50k6d27dxoaGnLTTTdVn1++fHluvfXW7LXXXkmSXXfdNW3atGmxZuHChZkzZ051zYABA9LU1JS77rqruubOO+9MU1NTizVz5szJwoULq2tmzJiRdu3aZdddd63xOwcAAAAAAHhF65IX//KXv5y99torEyZMyOGHH5677ror//3f/53//u//TvLKx5KNHTs2EyZMSJ8+fdKnT59MmDAhHTt2zPDhw5Mk9fX1OfbYY3PyySdn0003Tbdu3TJu3LjsuOOO2X///ZO8crfOgQcemOOPPz6XXHJJkuTzn/98hg4dmr59+yZJBg8enH79+mXkyJGZOHFinnnmmYwbNy7HH3+8O2YAAAAAAID1pmis2X333XPdddfl9NNPz1lnnZXevXvnwgsvzIgRI6prTj311CxdujSjR49OY2Nj9thjj8yYMSOdO3eurvn2t7+d1q1b5/DDD8/SpUuz33775fLLL0+rVq2qa6ZOnZoxY8Zk8ODBSZJDDjkkkydPrj7fqlWr3HDDDRk9enT23nvvdOjQIcOHD8/555//NkwCAAAAAADYUNVVKpVK6U28VzQ3N6e+vj5NTU3uxlkP6upqf84N/bffTGvLPGvPTGvPTGvLPGvPTGtrfcwzMdNa25DnmZhprZln7Zlp7ZlpbZln7ZlpbfmbtPb8jr67rGk3KPqdNQAAAAAAABs6sQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAgsQYAAAAAAKAg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TD760Y/mAx/4QLbeeutMnTo1I0aMqPU+AQAAAAAA3pPW6c6aZ555Jr17907yyvfTPPPMM0mSffbZJ3/4wx9qtzsAAAAAAID3uHWKNe9///vz6KOPJkn69euXn/70p0leueNmk002qdXeAAAAAAAA3vPWKdZ87nOfy7333pskOf3006vfXTN27NiccsopNd0gAAAAAADAe1ldpVKpvNWTzJ8/P/fcc08+8IEPZKeddqrFvt6VmpubU19fn6ampnTp0qX0dt5z6upqf863/tv/7mamtWWetWemtWemtWWetWemtbU+5pmYaa1tyPNMzLTWzLP2zLT2zLS2zLP2zLS2/E1ae35H313WtBus1Z01v/vd79KvX780Nze3OL7VVltlv/32y1FHHZX/+7//W7cdAwAAAAAAbIDWKtZceOGFOf7441dbf+rr63PCCSdk0qRJNdscAAAAAADAe91axZp77703Bx544Os+P3jw4MyaNWudNnL22Wenrq4uY8eOrR6rVCoZP358evXqlQ4dOmTQoEG5//77W7xu2bJlOemkk9K9e/d06tQphxxySB577LEWaxobGzNy5MjU19envr4+I0eOzLPPPttizfz58zNs2LB06tQp3bt3z5gxY7J8+fJ1ei8AAAAAAABraq1izRNPPJE2bdq87vOtW7fOk08+udabuPvuu/Pf//3fq3zfzXnnnZdJkyZl8uTJufvuu9PQ0JADDjggzz33XHXN2LFjc91112XatGmZOXNmnn/++QwdOjQrV66srhk+fHhmz56d6dOnZ/r06Zk9e3ZGjhxZfX7lypU5+OCDs2TJksycOTPTpk3Ltddem5NPPnmt3wsAAAAAAMDaWKtY8773vS/33Xff6z7/l7/8JZtvvvlabeD555/PiBEj8sMf/jBdu3atHq9UKrnwwgvzn//5nznssMPSv3//XHHFFXnhhRdy9dVXJ0mampoyZcqUXHDBBdl///2zyy675Mc//nHuu+++/Pa3v02SPPjgg5k+fXp+9KMfZcCAARkwYEB++MMf5le/+lX++te/JklmzJiRBx54ID/+8Y+zyy67ZP/9988FF1yQH/7wh6t8P8+/WrZsWZqbm1s8AAAAAAAA1sZaxZqDDjooX/va1/Liiy+u8tzSpUvz9a9/PUOHDl2rDXzxi1/MwQcfnP3337/F8blz52bRokUZPHhw9Vi7du0ycODA3HbbbUmSWbNmZcWKFS3W9OrVK/3796+uuf3221NfX5899tijumbPPfdMfX19izX9+/dPr169qmuGDBmSZcuWveHHup199tnVj1arr6/PlltuuVbvHQAAAAAAoPXaLD7jjDPy85//PNttt12+9KUvpW/fvqmrq8uDDz6Y733ve1m5cmX+8z//c43PN23atPzpT3/K3XffvcpzixYtSpL07NmzxfGePXtm3rx51TVt27ZtcUfOq2teff2iRYvSo0ePVc7fo0ePFmtee52uXbumbdu21TWrc/rpp+crX/lK9efm5mbBBgAAAAAAWCtrFWt69uyZ2267LV/4whdy+umnp1KpJEnq6uoyZMiQfP/7318leryeBQsW5N///d8zY8aMtG/f/nXX1dXVtfi5Uqmscuy1XrtmdevXZc1rtWvXLu3atXvDvQAAAAAAALyRtYo1SbL11lvn17/+dRobG/P3v/89lUolffr0WeXuljcza9asLF68OLvuumv12MqVK/OHP/whkydPrn6fzKJFi1p8D87ixYurQaihoSHLly9PY2Nji+svXrw4e+21V3XNE088scr1n3zyyRbnufPOO1s839jYmBUrVqxxfAIAAAAAAFgXa/WdNf+qa9eu2X333fORj3xkrUNNkuy333657777Mnv27Opjt912y4gRIzJ79uy8//3vT0NDQ2666abqa5YvX55bb721GmJ23XXXtGnTpsWahQsXZs6cOdU1AwYMSFNTU+66667qmjvvvDNNTU0t1syZMycLFy6srpkxY0batWvXIiYBAAAAAADU2lrfWVMrnTt3Tv/+/Vsc69SpUzbddNPq8bFjx2bChAnp06dP+vTpkwkTJqRjx44ZPnx4kqS+vj7HHntsTj755Gy66abp1q1bxo0blx133DH7779/kmT77bfPgQcemOOPPz6XXHJJkuTzn/98hg4dmr59+yZJBg8enH79+mXkyJGZOHFinnnmmYwbNy7HH398unTp8naNBAAAAAAA2AAVizVr4tRTT83SpUszevToNDY2Zo899siMGTPSuXPn6ppvf/vbad26dQ4//PAsXbo0++23Xy6//PK0atWqumbq1KkZM2ZMBg8enCQ55JBDMnny5OrzrVq1yg033JDRo0dn7733TocOHTJ8+PCcf/75b9+bBQAAAAAANkh1lUqlUnoT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AAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYg0AAAAAAEBBYs0mrr322gwcODA77bRTRowYkYceeqj0SAAAAAAAwHZMrPkTP/rRjzJ58uR8+ctfzs9//vP89//+33PMMcdk8eLFpUcDAAAAAAC2U2LNn7j66qtz6qmn5nOf+1z23XfffOtb30q/fv1y3XXXlR4NAAAAAADYTnUsPcC2Yt26dVmwYEG++MUvtru9ubk5jzzyyFu+zdq1a7N27dq211tbW5MkK1eu3HKD1qiGqQ1VeJTWD/wIW+T/TKH/33ZaXfZZfXZafdvCTrfYR+7PfXXtwM/RxE7b20b3mfhzX201+xxN7PT/Z5/VZ6fVZ6fVZZ/VZ6fV53PS6vIc3fH8sRdUKpW3PSfW/D//+Z//mQ0bNqRPnz7tbu/Tp0+WLVv2lm8zderU/P3f//1mt/fr12+LzMgH/4usGn8Vbv6gW+RRtxI7rS77rD47rb4PNvsW+8hrdqeeo9Vnp9W1je4zsdNqq9l9JnZabfZZfXZafXZaXfZZfXZaXdvoPhM7rbaa3efWsWrVqjS8zY7Emk3U1dW1e71SqWx22x9deumlueCCC9pe37hxY1599dXstttuf/ZteG9WrlyZfv36ZcmSJenevXvpcbYLdlpd9ll9dlpd9ll9dlp9dlpd9ll9dlp9dlpd9ll9dlpd9ll9dlp9dlpd9ll9dlq7KpVKVq1alaamprc9J9b8P7169UqHDh02u4pm+fLlm11t80f19fWpr69vd9uuu+66pUbcoXXv3t1fQlVmp9Vln9Vnp9Vln9Vnp9Vnp9Vln9Vnp9Vnp9Vln9Vnp9Vln9Vnp9Vnp9Vln9Vnp7Xp7a6o+aO/2Apz1ITOnTtnxIgRmTNnTrvb58yZk1GjRhWaCgAAAAAA2N65suZPXHDBBWlpackBBxyQkSNH5vrrr8/ixYtz5plnlh4NAAAAAADYTok1f+Kkk07K73//+3zta1/L0qVLM3To0Nx9990ZMGBA6dF2WPX19fnqV7+62Y+b4/2z0+qyz+qz0+qyz+qz0+qz0+qyz+qz0+qz0+qyz+qz0+qyz+qz0+qz0+qyz+qz0+1fXaVSqZQeAgAAAAAAYEfld9YAAAAAAAAUJNYAAAAAAAAUJNYAAAAAAAAUJNYAAAAAAAAUJNawTfrXf/3XjBs3Lk1NTamrq8udd95ZeqSaNnXq1Bx44IHp1q1bevfunU9+8pN54YUXSo9V06677rp85CMfSffu3dO9e/eMHDky99xzT+mxthtTp05NXV1dJk+eXHqUmnXZZZelrq6u3UtjY2PpsWref/zHf+Tv/u7vsttuu2XnnXfORz/60SxYsKD0WDVpjz322Ow5WldXl7PPPrv0aDXrzTffzP/8n/8zAwcOTJcuXfLhD384X/va17Jx48bSo9WsVatWZfLkyRkwYEC6dOmSUaNGZf78+aXHqhnv9Dl9pVLJZZddlqampnTp0iWHH354nn322TLD1oh32untt9+eMWPGpFevXqmrq8vChQuLzFlL3m6n69evzyWXXJJhw4ala9euaWpqysknn5yXXnqp3MDbuHd6jl522WXZZ5990rVr1/To0SNHHnlkHnvssTLD1oj38v2RM844I3V1dfnWt7611earNe+0z0mTJm32+enBBx9cZtga8W6eo88991zGjx+fhoaGdOvWLQcffHAWL1689YetEe+007f6Oqquri5XXnllmYGpGrGGbdLq1aszfPjwTJs2rfQo24W5c+fm7LPPzrx58zJnzpy8+eabaW5uzurVq0uPVrM+9KEP5Rvf+EaeeOKJPPHEE/nEJz6R4447zjcYqmD+/Pm5/vrr85GPfKT0KDVvv/32y9KlS9tenn766dIj1bQVK1bkkEMOSadOnXLPPffk3//933PVVVdl1113LT1aTZo/f3675+ecOXOSJJ/+9KcLT1a7Lr/88nznO9/JtGnT8txzz+WKK67IlVdemX/8x38sPVrN+tznPpc5c+bk5ptvztNPP53m5uYceeSR+Y//+I/So9WEd/qc/oorrsjVV1+dadOmZf78+WlsbMxRRx2VVatWbeVJa8c77XT16tU55JBD8o1vfGMrT1a73m6nb7zxRp588sl85StfyZNPPpnbb789v/jFLzJ+/PgCk9aGd3qO7r333pk2bVqefvrpPPzww9ljjz3S3NycV155ZStPWjve7fdH7rzzzjz22GNpamraSpPVpnezz6OPPrrd56l33333Vpyw9rzTTn/961/n0EMPzT777JMHH3ww//Zv/5avfOUr2WmnnbbypLXjnXb6p8/PpUuX5sYbb0xdXV0+9alPbeVJqboKbOOSVO64447SY2xXli9fXklSmTt3bulRtis9evSo/NM//VPpMWraqlWrKoMGDarMmTOnMnr06Mr5559feqSa9dWvfrUyfPjw0mNsVy655JLKoYceWnqM7db5559f2XPPPSsbN24sPUrNOvbYYyunnHJKu9tOOOGEyt/93d8Vmqi2vfHGG5UOHTpUfvrTn7a7ffjw4ZUvf/nLhaaqXZt+Tr9x48ZKY2Nj5Rvf+EbbbX/4wx8qDQ0Nle985zsFJqw9b/d10qJFiypJKj//+c+36ky17t187fn4449XklR++9vfbp2hati72Wdra2slSeW+++7bOkPVuD+309/97neVv/zLv6w888wzlQEDBlSuueaarT5bLXqrfU6cOLFy3HHHFZlne/BWOz3ppJN8PvoBvJu/S4877rjKJz7xia0zEFuUK2tgB9Ta2pok6dmzZ+FJtg8bNmzIzJkzs3r16owcObL0ODXt7LPPzrHHHpsjjzyy9CjbhV/+8pdpamrKwIED85nPfCa/+c1vSo9U037yk5/kgAMOyKc//en07t07+++/f773ve+VHmu7sG7duvzgBz/IKaeckrq6utLj1KxDDz00P/vZz/KLX/wiSfJv//Zvefjhh/NXf/VXhSerTW+++WY2bNiw2b/67NKlSx5++OFCU20/Fi1alGXLlqW5ubnttvr6+owePTqPPPJIwcng7bW2tqaurs6VtVWwbt26XH/99WloaMjw4cNLj1OzNm7cmJaWllx88cXZb7/9So+zXXjwwQfTu3fv7L333jnttNOyfPny0iPVrI0bN+auu+7K3nvvnTFjxqR379456KCD/LqDKnr55Zdz11135dRTTy09ClUg1sAOplKp5IILLsihhx6aoUOHlh6npj399NPZZZddUl9fnzPPPDN33HFHhgwZUnqsmjVz5sw8+eSTmTp1aulRtgsHHXRQvv/97+fee+/N9773vSxbtiyjRo3K73//+9Kj1azf/OY3ue666zJo0KDce++9OfPMM3Peeefl+9//funRat6dd96Z1157LZMmTSo9Sk275JJL8jd/8zfZZ5990qlTp+y///6ZPHly/uZv/qb0aDWpW7duGTlyZP73//7feemll7Jhw4b84Ac/yGOPPZalS5eWHq/mLVu2LEnSp0+fdrf36dOn7T7Y1vzhD3/IF7/4xUyYMCHdu3cvPU7N+ulPf5pddtklO+20U6655prMmTMnvXr1Kj1Wzbr88svTsWPHnHfeeaVH2S4cc8wxueWWW3L//ffnqquuyvz58/OJT3wia9euLT1aTVq+fHlef/31fOMb38jRRx+d2bNn5/jjj88JJ5yQuXPnlh5vu3DTTTelW7duOeGEE0qPQhV0LD0AsHWdc845eeqpp/yL0CoYPHhwFi5cmNdeey233XZbJk6cmLlz5wo278OSJUty/vnnZ/bs2X5ubZUcc8wxbf89bNiwjBw5MnvuuWduuummXHDBBQUnq10bN27MAQcckClTpiRJ9t9//zz77LO57rrrcvLJJxeerrbdcMMNOeaYY/yM9Q/oRz/6UX7wgx/khz/8Yfbbb78sXLgwkydPTlNTUyZOnFh6vJp0880355RTTslf/uVfpkOHDvnYxz6WCRMm5Mknnyw92nZj06vpKpWKK+zYJq1fvz6f+cxnsnHjxlx77bWlx6lpH//4x7Nw4cL853/+Z773ve/lxBNPzGOPPZbevXuXHq3mLFiwIN/+9rfz5JNP+ruzSk466aS2/x46dGgOOOCADBgwIHfddZdvhr8PGzduTJIcd9xx+fznP58k+ehHP5pHHnkk3/nOdzJ69OiS420Xbrzxxvzt3/6t76VsJ1xZAzuQc889Nz/5yU/ywAMP5EMf+lDpcWpe586ds9dee+WAAw7I1KlTM3z48Hz7298uPVZNWrBgQZYvX54RI0akY8eO6dixY+bOnZv/83/+Tzp27JgNGzaUHrHmde3aNcOGDcsvf/nL0qPUrL59+24WY/fdd98sXry40ETbh9/+9re577778rnPfa70KDXv4osvzhe/+MV85jOfybBhw9LS0pLPf/7zrlj8APbcc8/MnTs3r7/+epYsWZLHH38869evz8CBA0uPVvMaGxuTZLOraJYvX77Z1TZQ2vr163PiiSdm0aJFmTNnjqtqPqCuXbtmr732ysEHH5wbbrghHTt2zA033FB6rJr00EMPZfny5enfv3/b11G//e1vc+GFF2aPPfYoPd52oW/fvhkwYICvo96nXr16pWPHjr6O2kIeeuihvPDCC76W2o6INbADqFQqOeecc3L77bfn/vvv9w2GLaRSqbg0+n064ogj8vTTT2fhwoVtLwcccED+9m//NgsXLkyHDh1Kj1jz1q5dm+eeey59+/YtPUrNOuSQQ/LCCy+0u+0Xv/hFBgwYUGii7cP06dPTu3fvHHvssaVHqXlvvPFG/uIv2n9636FDh7Z/0cj717Vr1/Tt2zcrVqzIvffem+OOO670SDVv4MCBaWxszJw5c9puW7duXebOnZtRo0YVnAza+2Oo+eUvf5n77rsvu+22W+mRtju+jnr/Wlpa8tRTT7X7OqqpqSkXX3xx7r333tLjbRd+//vfZ8mSJb6Oep86d+6cAw880NdRW8gNN9yQESNG+L1f2xE/Bo1t0uuvv55f/epXba8vWrQoCxcuTM+ePdO/f/+Ck9Wms88+Oz/84Q/z4x//ON26dWv7F4wNDQ3p0qVL4elq05e+9KUcc8wx6devX1atWpWZM2fmwQcfzKxZs0qPVpO6deu22e9Q6tq1a3bbbTe/W+l9uuiiizJu3Lj0798/y5cvzz/8wz9k5cqVfhTSB/D5z38+o0aNypQpU3LiiSfm8ccfz/XXX5/rr7++9Gg1a+PGjZk+fXomTpyYjh19WvpBjRs3Ll//+tfTv3//7Lfffvn5z3+eq6++Oqecckrp0WrWvffem0qlksGDB+dXv/pVLr744gwePDif/exnS49WE97pc/rJkydnypQpGTRoUAYNGpQpU6Zk5513zoQJEwpOvW17p52++uqrWbx4cV566aUkafvmWGNjY9vVTLT3djttamrKX//1X+fJJ5/MT3/602zYsKHta6mePXumc+fOpcbeZr3dPnfbbbd8/etfz/jx49O3b9/8/ve/z7XXXpvf/e53+fSnP11w6m3bO/253zQgdurUKY2NjRk8ePDWHrUmvN0+e/bsmcsuuyyf+tSn0rdv37z44ov50pe+lF69euX4448vOPW27Z2eoxdffHFOOumkHHbYYfn4xz+eWbNm5V/+5V/y4IMPlht6G/duvi+6cuXK/PM//3OuuuqqUmOyJVRgG/TAAw9Ukmz2MnHixNKj1aS32mWSyvTp00uPVrNOOeWUyoABAyqdO3eu7L777pUjjjiiMnv27NJjbVdGjx5dOf/880uPUbNOOumkSt++fSudOnWqNDU1VU444YTKs88+W3qsmvcv//IvlaFDh1bq6+sr++yzT+X6668vPVJNu/feeytJKi+88ELpUbYLK1eurJx//vmV/v37V3baaafKhz/84cqXv/zlytq1a0uPVrN+9KMfVT784Q9XOnfuXGlsbKycffbZlddee630WDXjnT6n37hxY+WrX/1qpbGxsVJfX1857LDDKk8//XTZobdx77TT6dOnv+X9X/3qV4vOvS17u50uWrToz34t9cADD5QefZv0dvtcs2ZN5fjjj680NTVVOnfuXOnbt29l/Pjxlccff7z02Nu09/r9kQEDBlSuueaarTpjLXm7fb7xxhuV5ubmyu67717p1KlTpX///pWJEydWFi9eXHrsbdq7eY7ecMMNlb322quy0047VYYPH1658847yw1cA97NTr/73e9WunTp4nPT7UxdpVKpVKH5AAAAAAAA8D74nTUAAAAAAAAFiTUAAAAAAAAFiTUAAAAAAAAFiTUAAAAAAAAFiTUAAAAAAAAFiTUAAAAAAAAFiTUAAAAAAAAFiTUAAAAAAAAFiTUAAAA15PDDD8/kyZNLjwEAAFSRWAMAANS8SZMmpa6uLmeeeeZm95111lmpq6vLpEmTkvz52HHnnXemrq4uSXLVVVeloaEhb7zxxmbn/vCHP2TXXXfN1Vdf/Y5z1dXV5c4773xPHwsAALDjEWsAAIDtQr9+/TJz5sysWbOm7bY//OEPufXWW9O/f//39Fgnn3xy1qxZk9tuu22z+2677ba88cYbaWlp+cAzAwAAJGINAACwnfjYxz6W/v375/bbb2+77fbbb0+/fv2y//77v6fH2n333TNu3LjceOONm9134403Zvz48dl9993f9jH22GOPJMnxxx+furq6ttd//etf57jjjkufPn2yyy675MADD8x9993X7m2vvfbaDBo0KDvttFP69OmTv/7rv/6z72fWrFlpaGjI97///STJgw8+mP/23/5bunbtml133TWHHHJIfvvb376Hjx4AANjaxBoAAGC78dnPfjbTp09ve/3GG2/MKaec8r4e69RTT83cuXOzaNGitttefPHFPPDAAzn11FPf8e3nz5+fJJk+fXqWLl3a9vrrr7+ev/qrv8p9992Xn//85xkzZkzGjRuXxYsXJ0meeOKJnHfeefna176WF154IbNmzcphhx32lu9j5syZOfHEE/P9738/J598ct5888188pOfzOjRo/PUU0/l0Ucfzemnn972490AAIBtU8fSAwAAAFRLS0tLLr300rz44oupq6vL//2//zczZ87Mgw8++J4fa8yYMWlqasqMGTPy93//90n+K7w0NTWlubn5Hd/+j1fe7LrrrmlsbGy7ffjw4Rk+fHjb6//wD/+QO+64Iz/5yU9yzjnnZPHixenatWvGjh2bbt26ZcCAAW95ZdC1116bL33pS/nxj3+cj3/840mSlStXprW1NWPHjs2ee+6ZJNl3333f88cOAABsXa6sAQAAthu9evXKsccem5tuuinTp0/Psccem169er2vx+rQoUMmTpyYGTNmZOPGjalUKrnpppsyadKkdOjQ4X3PuHr16nzhC1/IkCFDsuuuu2aXXXbJ888/33ZlzVFHHZUBAwbkwx/+cFpaWnLLLbfkjTfeaPcYt912WyZPnpzZs2e3hZok6dmzZyZNmtR2tc63v/3tLF269H3PCgAAbB1iDQAAsF055ZRTMmPGjNx0001v+SPQunfvntbW1s1uf+2119K9e/fNHmvJkiW5//7787Of/SyLFy/OZz/72Q8038UXX5zbbrstX//61/PQQw9l4cKFGTZsWNatW5ck6datW5588snceuut6du3b/7X//pfGT58eF577bW2x/joRz+a3XffPdOnT0+lUmn3+NOnT8+jjz6aUaNG5Uc/+lH23nvvzJs37wPNDAAAbFliDQAAsF05+uijs27duqxbty5jxozZ7P599tknTzzxxGa3z58/P4MHD25325577pnRo0dn+vTpufHGG3P44Ye3/Xixd6NTp07ZsGFDu9seeuihTJo0Kccff3yGDRuWxsbGvPjii+3OdOzYMUceeWSuuOKKPPXUU3nxxRdz//33t5vrgQceyI9//OOce+65m73f/fffP5deemkeeeSRDB06ND/84Q/f9cwAAMDW53fWAAAA25UOHTrkueeea/vvTZ111lmZNm1azj777Jx++unp0qVL5syZkxtuuCE333zzZudPPfXUnHbaaUmSf/qnf3pPs+yxxx752c9+lkMOOST19fXp0aNH9tprr9x+++0ZN25c6urq8pWvfCUbN25se5uf/vSn+c1vfpPDDjssPXr0yN13352NGzduFpL23nvvPPDAAzn88MPTsWPHfOtb38qiRYty/fXXZ/z48WlqasoLL7yQX/ziFzn55JPf09wAAMDW5coaAABgu9O9e/fNfqTZH+2xxx556KGH8utf/zrNzc058MADM2PGjMyYMSOf/vSnNzv/qU99KvX19amvr88JJ5zwnua46qqrMmfOnPTr1y/7779/kuSaa65Jjx49MmrUqIwbNy5jxozJxz72sba32XXXXXP77bfnE5/4RPbdd9985zvfya233pr99ttvs8cfPHhw7r///tx666258MILs/POO+f555/Ppz71qey99945/fTTc8455+SMM854T3MDAABbV11l0x9wDAAAAAAAwFbjyhoAAAAAAICCxBoAAID34ZZbbskuu+zyli9v9SPLAAAA/hw/Bg0AAOB9WLVqVV5++eW3vK9Tp04ZMGDAVp4IAACoVWINAAAAAABAQX4MGgAAAAAAQEFiDQAAAAAAQEFiDQAAAAAAQEFiDQAAAAAAQEFiDQAAAAAAQEFiDQAAAAAAQEFiDQAAAAAAQEH/H9cYC9zD4zd2AAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 2000x1500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Importing the matplotlib library\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "# Declaring the figure or the plot (y, x) or (width, height)\n",
    "plt.figure(figsize=[20, 15])\n",
    "\n",
    "X = np.arange(1,len(muv_tasks)+1)\n",
    "plt.bar(X + 0.2, one, color = 'g', width = 0.25)\n",
    "plt.bar(X + 0.4, zero, color = 'b', width = 0.25)\n",
    "plt.bar(X + 0.6, nan, color = 'r', width = 0.25)\n",
    "\n",
    "# Creating the legend of the bars in the plot\n",
    "plt.legend(['Active' , 'Inactive' ,'NAN'])\n",
    "# Overiding the x axis with the country names\n",
    "plt.xticks([i + 0.25 for i in range(1,18)], X)\n",
    "# Giving the tilte for the plot\n",
    "plt.title(\"MUV dataset diagram\")\n",
    "# Namimg the x and y axis\n",
    "plt.xlabel('MUV_tasks')\n",
    "plt.ylabel('Cases')\n",
    "# Saving the plot as a 'png'\n",
    "plt.savefig('4BarPlot.png')\n",
    "# Displaying the bar plot\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true,
    "id": "6grIE_JeqkUZ"
   },
   "source": [
    "# Required functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "hidden": true,
    "id": "m9K0ArLh6BC1"
   },
   "outputs": [],
   "source": [
    "from dgllife.model import MLPPredictor\n",
    "\n",
    "def create_dataset_with_gcn(dataset, class_embed_vector, GCN, tasks, numberTask):\n",
    "\n",
    "    created_data = []\n",
    "    data = np.arange(len(tasks))\n",
    "    onehot_encoded = to_categorical(data)\n",
    "\n",
    "    for i, data in enumerate(dataset):\n",
    "        smiles, g, label, mask = data\n",
    "        g = g.to(device)\n",
    "        g = dgl.add_self_loop(g)\n",
    "        graph_feats = g.ndata.pop('h')\n",
    "        embbed = GCN(g, graph_feats)\n",
    "        embbed = embbed.to('cpu')\n",
    "        embbed = embbed.detach().numpy()\n",
    "        a = ( embbed, onehot_encoded[numberTask], class_embed_vector[numberTask], label, tasks[numberTask])\n",
    "        created_data.append(a)\n",
    "    print('Data created!!')\n",
    "    return created_data \n",
    "\n",
    "\n",
    "def create_meta_data_gcn(GCN, dataset, class_embed_vector, train_task_size, tasks):\n",
    "    \n",
    "    train_data= []\n",
    "    valid_data = []\n",
    "    data = np.arange(len(tasks))\n",
    "    onehot_encoded = to_categorical(data)\n",
    "    \n",
    "    for numberTask , datas in enumerate(dataset):\n",
    "        \n",
    "        for j, data in enumerate(datas):\n",
    "            \n",
    "            smiles, g, label, mask = data\n",
    "            \n",
    "            g = g.to(device)\n",
    "            g = dgl.add_self_loop(g)\n",
    "            graph_feats = g.ndata.pop('h')\n",
    "            embbed = GCN(g, graph_feats)\n",
    "            embbed = embbed.to('cpu')\n",
    "            embbed = embbed.detach().numpy()\n",
    "            a = (smiles, embbed, onehot_encoded[numberTask], class_embed_vector[numberTask], label[0], tasks[numberTask])\n",
    "\n",
    "            \n",
    "            if numberTask < train_task_size :\n",
    "                train_data.append(a)\n",
    "            else:\n",
    "                valid_data.append(a)\n",
    "\n",
    "    print('Data created!!')            \n",
    "    return train_data, valid_data "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Calculation of embedded vectors for each class "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MUV-466=> positive: 27 - negative: 14814\n",
      "MUV-548=> positive: 29 - negative: 14705\n",
      "MUV-600=> positive: 30 - negative: 14698\n",
      "MUV-644=> positive: 30 - negative: 14593\n",
      "MUV-652=> positive: 29 - negative: 14873\n",
      "MUV-689=> positive: 29 - negative: 14572\n",
      "MUV-692=> positive: 30 - negative: 14614\n",
      "MUV-712=> positive: 28 - negative: 14383\n",
      "MUV-713=> positive: 29 - negative: 14807\n",
      "MUV-733=> positive: 28 - negative: 14654\n",
      "MUV-737=> positive: 29 - negative: 14662\n",
      "MUV-810=> positive: 29 - negative: 14615\n",
      "MUV-832=> positive: 30 - negative: 14637\n",
      "MUV-846=> positive: 30 - negative: 14681\n",
      "MUV-852=> positive: 29 - negative: 14622\n",
      "MUV-858=> positive: 29 - negative: 14745\n",
      "MUV-859=> positive: 24 - negative: 14722\n"
     ]
    }
   ],
   "source": [
    "df_positive, df_negative = separate_active_and_inactive_data(df, muv_tasks)\n",
    "\n",
    "for i,d in enumerate(zip(df_positive,df_negative)):\n",
    "    print(f'{muv_tasks[i]}=> positive: {len(d[0])} - negative: {len(d[1])}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14814\n",
      "Processing molecule 2000/14814\n",
      "Processing molecule 3000/14814\n",
      "Processing molecule 4000/14814\n",
      "Processing molecule 5000/14814\n",
      "Processing molecule 6000/14814\n",
      "Processing molecule 7000/14814\n",
      "Processing molecule 8000/14814\n",
      "Processing molecule 9000/14814\n",
      "Processing molecule 10000/14814\n",
      "Processing molecule 11000/14814\n",
      "Processing molecule 12000/14814\n",
      "Processing molecule 13000/14814\n",
      "Processing molecule 14000/14814\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14705\n",
      "Processing molecule 2000/14705\n",
      "Processing molecule 3000/14705\n",
      "Processing molecule 4000/14705\n",
      "Processing molecule 5000/14705\n",
      "Processing molecule 6000/14705\n",
      "Processing molecule 7000/14705\n",
      "Processing molecule 8000/14705\n",
      "Processing molecule 9000/14705\n",
      "Processing molecule 10000/14705\n",
      "Processing molecule 11000/14705\n",
      "Processing molecule 12000/14705\n",
      "Processing molecule 13000/14705\n",
      "Processing molecule 14000/14705\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14698\n",
      "Processing molecule 2000/14698\n",
      "Processing molecule 3000/14698\n",
      "Processing molecule 4000/14698\n",
      "Processing molecule 5000/14698\n",
      "Processing molecule 6000/14698\n",
      "Processing molecule 7000/14698\n",
      "Processing molecule 8000/14698\n",
      "Processing molecule 9000/14698\n",
      "Processing molecule 10000/14698\n",
      "Processing molecule 11000/14698\n",
      "Processing molecule 12000/14698\n",
      "Processing molecule 13000/14698\n",
      "Processing molecule 14000/14698\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14593\n",
      "Processing molecule 2000/14593\n",
      "Processing molecule 3000/14593\n",
      "Processing molecule 4000/14593\n",
      "Processing molecule 5000/14593\n",
      "Processing molecule 6000/14593\n",
      "Processing molecule 7000/14593\n",
      "Processing molecule 8000/14593\n",
      "Processing molecule 9000/14593\n",
      "Processing molecule 10000/14593\n",
      "Processing molecule 11000/14593\n",
      "Processing molecule 12000/14593\n",
      "Processing molecule 13000/14593\n",
      "Processing molecule 14000/14593\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14873\n",
      "Processing molecule 2000/14873\n",
      "Processing molecule 3000/14873\n",
      "Processing molecule 4000/14873\n",
      "Processing molecule 5000/14873\n",
      "Processing molecule 6000/14873\n",
      "Processing molecule 7000/14873\n",
      "Processing molecule 8000/14873\n",
      "Processing molecule 9000/14873\n",
      "Processing molecule 10000/14873\n",
      "Processing molecule 11000/14873\n",
      "Processing molecule 12000/14873\n",
      "Processing molecule 13000/14873\n",
      "Processing molecule 14000/14873\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14572\n",
      "Processing molecule 2000/14572\n",
      "Processing molecule 3000/14572\n",
      "Processing molecule 4000/14572\n",
      "Processing molecule 5000/14572\n",
      "Processing molecule 6000/14572\n",
      "Processing molecule 7000/14572\n",
      "Processing molecule 8000/14572\n",
      "Processing molecule 9000/14572\n",
      "Processing molecule 10000/14572\n",
      "Processing molecule 11000/14572\n",
      "Processing molecule 12000/14572\n",
      "Processing molecule 13000/14572\n",
      "Processing molecule 14000/14572\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14614\n",
      "Processing molecule 2000/14614\n",
      "Processing molecule 3000/14614\n",
      "Processing molecule 4000/14614\n",
      "Processing molecule 5000/14614\n",
      "Processing molecule 6000/14614\n",
      "Processing molecule 7000/14614\n",
      "Processing molecule 8000/14614\n",
      "Processing molecule 9000/14614\n",
      "Processing molecule 10000/14614\n",
      "Processing molecule 11000/14614\n",
      "Processing molecule 12000/14614\n",
      "Processing molecule 13000/14614\n",
      "Processing molecule 14000/14614\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14383\n",
      "Processing molecule 2000/14383\n",
      "Processing molecule 3000/14383\n",
      "Processing molecule 4000/14383\n",
      "Processing molecule 5000/14383\n",
      "Processing molecule 6000/14383\n",
      "Processing molecule 7000/14383\n",
      "Processing molecule 8000/14383\n",
      "Processing molecule 9000/14383\n",
      "Processing molecule 10000/14383\n",
      "Processing molecule 11000/14383\n",
      "Processing molecule 12000/14383\n",
      "Processing molecule 13000/14383\n",
      "Processing molecule 14000/14383\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14807\n",
      "Processing molecule 2000/14807\n",
      "Processing molecule 3000/14807\n",
      "Processing molecule 4000/14807\n",
      "Processing molecule 5000/14807\n",
      "Processing molecule 6000/14807\n",
      "Processing molecule 7000/14807\n",
      "Processing molecule 8000/14807\n",
      "Processing molecule 9000/14807\n",
      "Processing molecule 10000/14807\n",
      "Processing molecule 11000/14807\n",
      "Processing molecule 12000/14807\n",
      "Processing molecule 13000/14807\n",
      "Processing molecule 14000/14807\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14654\n",
      "Processing molecule 2000/14654\n",
      "Processing molecule 3000/14654\n",
      "Processing molecule 4000/14654\n",
      "Processing molecule 5000/14654\n",
      "Processing molecule 6000/14654\n",
      "Processing molecule 7000/14654\n",
      "Processing molecule 8000/14654\n",
      "Processing molecule 9000/14654\n",
      "Processing molecule 10000/14654\n",
      "Processing molecule 11000/14654\n",
      "Processing molecule 12000/14654\n",
      "Processing molecule 13000/14654\n",
      "Processing molecule 14000/14654\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14662\n",
      "Processing molecule 2000/14662\n",
      "Processing molecule 3000/14662\n",
      "Processing molecule 4000/14662\n",
      "Processing molecule 5000/14662\n",
      "Processing molecule 6000/14662\n",
      "Processing molecule 7000/14662\n",
      "Processing molecule 8000/14662\n",
      "Processing molecule 9000/14662\n",
      "Processing molecule 10000/14662\n",
      "Processing molecule 11000/14662\n",
      "Processing molecule 12000/14662\n",
      "Processing molecule 13000/14662\n",
      "Processing molecule 14000/14662\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14615\n",
      "Processing molecule 2000/14615\n",
      "Processing molecule 3000/14615\n",
      "Processing molecule 4000/14615\n",
      "Processing molecule 5000/14615\n",
      "Processing molecule 6000/14615\n",
      "Processing molecule 7000/14615\n",
      "Processing molecule 8000/14615\n",
      "Processing molecule 9000/14615\n",
      "Processing molecule 10000/14615\n",
      "Processing molecule 11000/14615\n",
      "Processing molecule 12000/14615\n",
      "Processing molecule 13000/14615\n",
      "Processing molecule 14000/14615\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14637\n",
      "Processing molecule 2000/14637\n",
      "Processing molecule 3000/14637\n",
      "Processing molecule 4000/14637\n",
      "Processing molecule 5000/14637\n",
      "Processing molecule 6000/14637\n",
      "Processing molecule 7000/14637\n",
      "Processing molecule 8000/14637\n",
      "Processing molecule 9000/14637\n",
      "Processing molecule 10000/14637\n",
      "Processing molecule 11000/14637\n",
      "Processing molecule 12000/14637\n",
      "Processing molecule 13000/14637\n",
      "Processing molecule 14000/14637\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14681\n",
      "Processing molecule 2000/14681\n",
      "Processing molecule 3000/14681\n",
      "Processing molecule 4000/14681\n",
      "Processing molecule 5000/14681\n",
      "Processing molecule 6000/14681\n",
      "Processing molecule 7000/14681\n",
      "Processing molecule 8000/14681\n",
      "Processing molecule 9000/14681\n",
      "Processing molecule 10000/14681\n",
      "Processing molecule 11000/14681\n",
      "Processing molecule 12000/14681\n",
      "Processing molecule 13000/14681\n",
      "Processing molecule 14000/14681\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14622\n",
      "Processing molecule 2000/14622\n",
      "Processing molecule 3000/14622\n",
      "Processing molecule 4000/14622\n",
      "Processing molecule 5000/14622\n",
      "Processing molecule 6000/14622\n",
      "Processing molecule 7000/14622\n",
      "Processing molecule 8000/14622\n",
      "Processing molecule 9000/14622\n",
      "Processing molecule 10000/14622\n",
      "Processing molecule 11000/14622\n",
      "Processing molecule 12000/14622\n",
      "Processing molecule 13000/14622\n",
      "Processing molecule 14000/14622\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14745\n",
      "Processing molecule 2000/14745\n",
      "Processing molecule 3000/14745\n",
      "Processing molecule 4000/14745\n",
      "Processing molecule 5000/14745\n",
      "Processing molecule 6000/14745\n",
      "Processing molecule 7000/14745\n",
      "Processing molecule 8000/14745\n",
      "Processing molecule 9000/14745\n",
      "Processing molecule 10000/14745\n",
      "Processing molecule 11000/14745\n",
      "Processing molecule 12000/14745\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Processing molecule 13000/14745\n",
      "Processing molecule 14000/14745\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14722\n",
      "Processing molecule 2000/14722\n",
      "Processing molecule 3000/14722\n",
      "Processing molecule 4000/14722\n",
      "Processing molecule 5000/14722\n",
      "Processing molecule 6000/14722\n",
      "Processing molecule 7000/14722\n",
      "Processing molecule 8000/14722\n",
      "Processing molecule 9000/14722\n",
      "Processing molecule 10000/14722\n",
      "Processing molecule 11000/14722\n",
      "Processing molecule 12000/14722\n",
      "Processing molecule 13000/14722\n",
      "Processing molecule 14000/14722\n"
     ]
    }
   ],
   "source": [
    "dataset_positive = [DATASET(d, smiles_to_bigraph, AttentiveFPAtomFeaturizer(), cache_file_path = cache_path) for d in df_positive]\n",
    "dataset_negative = [DATASET(d, smiles_to_bigraph, AttentiveFPAtomFeaturizer(), cache_file_path = cache_path) for d in df_negative]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "class vector created!!\n"
     ]
    }
   ],
   "source": [
    "embed_class_muv = get_embedding_vector_class(dataset_positive, dataset_negative, radius=2, size = 512)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true,
    "id": "XH-609VwgG4W"
   },
   "source": [
    "# Bioactivity class-based strategy (Meta-Learning) with BioAct-Het"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true,
    "id": "DQuTm_lmlOOM"
   },
   "source": [
    "## Meta-Learning with BioAct-Het and AttentiveFP GCN "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true,
    "hidden": true,
    "id": "LIx0yuwm6D42"
   },
   "source": [
    "### Siamea model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "hidden": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Downloading GCN_attentivefp_MUV_pre_trained.pth from https://data.dgl.ai/dgllife/pre_trained/gcn_attentivefp_muv.pth...\n",
      "Pretrained model loaded\n"
     ]
    }
   ],
   "source": [
    "model_name = 'GCN_attentivefp_MUV'\n",
    "gcn_model = get_muv_model(model_name)\n",
    "gcn_model.eval()\n",
    "gcn_model = gcn_model.to(device)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "hidden": true,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14841\n",
      "Processing molecule 2000/14841\n",
      "Processing molecule 3000/14841\n",
      "Processing molecule 4000/14841\n",
      "Processing molecule 5000/14841\n",
      "Processing molecule 6000/14841\n",
      "Processing molecule 7000/14841\n",
      "Processing molecule 8000/14841\n",
      "Processing molecule 9000/14841\n",
      "Processing molecule 10000/14841\n",
      "Processing molecule 11000/14841\n",
      "Processing molecule 12000/14841\n",
      "Processing molecule 13000/14841\n",
      "Processing molecule 14000/14841\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14734\n",
      "Processing molecule 2000/14734\n",
      "Processing molecule 3000/14734\n",
      "Processing molecule 4000/14734\n",
      "Processing molecule 5000/14734\n",
      "Processing molecule 6000/14734\n",
      "Processing molecule 7000/14734\n",
      "Processing molecule 8000/14734\n",
      "Processing molecule 9000/14734\n",
      "Processing molecule 10000/14734\n",
      "Processing molecule 11000/14734\n",
      "Processing molecule 12000/14734\n",
      "Processing molecule 13000/14734\n",
      "Processing molecule 14000/14734\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14728\n",
      "Processing molecule 2000/14728\n",
      "Processing molecule 3000/14728\n",
      "Processing molecule 4000/14728\n",
      "Processing molecule 5000/14728\n",
      "Processing molecule 6000/14728\n",
      "Processing molecule 7000/14728\n",
      "Processing molecule 8000/14728\n",
      "Processing molecule 9000/14728\n",
      "Processing molecule 10000/14728\n",
      "Processing molecule 11000/14728\n",
      "Processing molecule 12000/14728\n",
      "Processing molecule 13000/14728\n",
      "Processing molecule 14000/14728\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14623\n",
      "Processing molecule 2000/14623\n",
      "Processing molecule 3000/14623\n",
      "Processing molecule 4000/14623\n",
      "Processing molecule 5000/14623\n",
      "Processing molecule 6000/14623\n",
      "Processing molecule 7000/14623\n",
      "Processing molecule 8000/14623\n",
      "Processing molecule 9000/14623\n",
      "Processing molecule 10000/14623\n",
      "Processing molecule 11000/14623\n",
      "Processing molecule 12000/14623\n",
      "Processing molecule 13000/14623\n",
      "Processing molecule 14000/14623\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14902\n",
      "Processing molecule 2000/14902\n",
      "Processing molecule 3000/14902\n",
      "Processing molecule 4000/14902\n",
      "Processing molecule 5000/14902\n",
      "Processing molecule 6000/14902\n",
      "Processing molecule 7000/14902\n",
      "Processing molecule 8000/14902\n",
      "Processing molecule 9000/14902\n",
      "Processing molecule 10000/14902\n",
      "Processing molecule 11000/14902\n",
      "Processing molecule 12000/14902\n",
      "Processing molecule 13000/14902\n",
      "Processing molecule 14000/14902\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14601\n",
      "Processing molecule 2000/14601\n",
      "Processing molecule 3000/14601\n",
      "Processing molecule 4000/14601\n",
      "Processing molecule 5000/14601\n",
      "Processing molecule 6000/14601\n",
      "Processing molecule 7000/14601\n",
      "Processing molecule 8000/14601\n",
      "Processing molecule 9000/14601\n",
      "Processing molecule 10000/14601\n",
      "Processing molecule 11000/14601\n",
      "Processing molecule 12000/14601\n",
      "Processing molecule 13000/14601\n",
      "Processing molecule 14000/14601\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14644\n",
      "Processing molecule 2000/14644\n",
      "Processing molecule 3000/14644\n",
      "Processing molecule 4000/14644\n",
      "Processing molecule 5000/14644\n",
      "Processing molecule 6000/14644\n",
      "Processing molecule 7000/14644\n",
      "Processing molecule 8000/14644\n",
      "Processing molecule 9000/14644\n",
      "Processing molecule 10000/14644\n",
      "Processing molecule 11000/14644\n",
      "Processing molecule 12000/14644\n",
      "Processing molecule 13000/14644\n",
      "Processing molecule 14000/14644\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14411\n",
      "Processing molecule 2000/14411\n",
      "Processing molecule 3000/14411\n",
      "Processing molecule 4000/14411\n",
      "Processing molecule 5000/14411\n",
      "Processing molecule 6000/14411\n",
      "Processing molecule 7000/14411\n",
      "Processing molecule 8000/14411\n",
      "Processing molecule 9000/14411\n",
      "Processing molecule 10000/14411\n",
      "Processing molecule 11000/14411\n",
      "Processing molecule 12000/14411\n",
      "Processing molecule 13000/14411\n",
      "Processing molecule 14000/14411\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14836\n",
      "Processing molecule 2000/14836\n",
      "Processing molecule 3000/14836\n",
      "Processing molecule 4000/14836\n",
      "Processing molecule 5000/14836\n",
      "Processing molecule 6000/14836\n",
      "Processing molecule 7000/14836\n",
      "Processing molecule 8000/14836\n",
      "Processing molecule 9000/14836\n",
      "Processing molecule 10000/14836\n",
      "Processing molecule 11000/14836\n",
      "Processing molecule 12000/14836\n",
      "Processing molecule 13000/14836\n",
      "Processing molecule 14000/14836\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14682\n",
      "Processing molecule 2000/14682\n",
      "Processing molecule 3000/14682\n",
      "Processing molecule 4000/14682\n",
      "Processing molecule 5000/14682\n",
      "Processing molecule 6000/14682\n",
      "Processing molecule 7000/14682\n",
      "Processing molecule 8000/14682\n",
      "Processing molecule 9000/14682\n",
      "Processing molecule 10000/14682\n",
      "Processing molecule 11000/14682\n",
      "Processing molecule 12000/14682\n",
      "Processing molecule 13000/14682\n",
      "Processing molecule 14000/14682\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14691\n",
      "Processing molecule 2000/14691\n",
      "Processing molecule 3000/14691\n",
      "Processing molecule 4000/14691\n",
      "Processing molecule 5000/14691\n",
      "Processing molecule 6000/14691\n",
      "Processing molecule 7000/14691\n",
      "Processing molecule 8000/14691\n",
      "Processing molecule 9000/14691\n",
      "Processing molecule 10000/14691\n",
      "Processing molecule 11000/14691\n",
      "Processing molecule 12000/14691\n",
      "Processing molecule 13000/14691\n",
      "Processing molecule 14000/14691\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14644\n",
      "Processing molecule 2000/14644\n",
      "Processing molecule 3000/14644\n",
      "Processing molecule 4000/14644\n",
      "Processing molecule 5000/14644\n",
      "Processing molecule 6000/14644\n",
      "Processing molecule 7000/14644\n",
      "Processing molecule 8000/14644\n",
      "Processing molecule 9000/14644\n",
      "Processing molecule 10000/14644\n",
      "Processing molecule 11000/14644\n",
      "Processing molecule 12000/14644\n",
      "Processing molecule 13000/14644\n",
      "Processing molecule 14000/14644\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14667\n",
      "Processing molecule 2000/14667\n",
      "Processing molecule 3000/14667\n",
      "Processing molecule 4000/14667\n",
      "Processing molecule 5000/14667\n",
      "Processing molecule 6000/14667\n",
      "Processing molecule 7000/14667\n",
      "Processing molecule 8000/14667\n",
      "Processing molecule 9000/14667\n",
      "Processing molecule 10000/14667\n",
      "Processing molecule 11000/14667\n",
      "Processing molecule 12000/14667\n",
      "Processing molecule 13000/14667\n",
      "Processing molecule 14000/14667\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14711\n",
      "Processing molecule 2000/14711\n",
      "Processing molecule 3000/14711\n",
      "Processing molecule 4000/14711\n",
      "Processing molecule 5000/14711\n",
      "Processing molecule 6000/14711\n",
      "Processing molecule 7000/14711\n",
      "Processing molecule 8000/14711\n",
      "Processing molecule 9000/14711\n",
      "Processing molecule 10000/14711\n",
      "Processing molecule 11000/14711\n",
      "Processing molecule 12000/14711\n",
      "Processing molecule 13000/14711\n",
      "Processing molecule 14000/14711\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14651\n",
      "Processing molecule 2000/14651\n",
      "Processing molecule 3000/14651\n",
      "Processing molecule 4000/14651\n",
      "Processing molecule 5000/14651\n",
      "Processing molecule 6000/14651\n",
      "Processing molecule 7000/14651\n",
      "Processing molecule 8000/14651\n",
      "Processing molecule 9000/14651\n",
      "Processing molecule 10000/14651\n",
      "Processing molecule 11000/14651\n",
      "Processing molecule 12000/14651\n",
      "Processing molecule 13000/14651\n",
      "Processing molecule 14000/14651\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14774\n",
      "Processing molecule 2000/14774\n",
      "Processing molecule 3000/14774\n",
      "Processing molecule 4000/14774\n",
      "Processing molecule 5000/14774\n",
      "Processing molecule 6000/14774\n",
      "Processing molecule 7000/14774\n",
      "Processing molecule 8000/14774\n",
      "Processing molecule 9000/14774\n",
      "Processing molecule 10000/14774\n",
      "Processing molecule 11000/14774\n",
      "Processing molecule 12000/14774\n",
      "Processing molecule 13000/14774\n",
      "Processing molecule 14000/14774\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14746\n",
      "Processing molecule 2000/14746\n",
      "Processing molecule 3000/14746\n",
      "Processing molecule 4000/14746\n",
      "Processing molecule 5000/14746\n",
      "Processing molecule 6000/14746\n",
      "Processing molecule 7000/14746\n",
      "Processing molecule 8000/14746\n",
      "Processing molecule 9000/14746\n",
      "Processing molecule 10000/14746\n",
      "Processing molecule 11000/14746\n",
      "Processing molecule 12000/14746\n",
      "Processing molecule 13000/14746\n",
      "Processing molecule 14000/14746\n"
     ]
    }
   ],
   "source": [
    "data_ds = []\n",
    "cache_path='./muv_dglgraph.bin'\n",
    "for i, task in  enumerate(muv_tasks):\n",
    "    a = df[['smiles' , task]]\n",
    "    a = a.dropna()\n",
    "    ds = DATASET(a, smiles_to_bigraph, AttentiveFPAtomFeaturizer(), cache_file_path = cache_path)\n",
    "    data_ds.append(ds)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "hidden": true,
    "id": "HGiScGzpzl0h",
    "outputId": "3e682170-5ae9-4a77-c38f-39a61968107b"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Data created!!\n"
     ]
    }
   ],
   "source": [
    "train_dataset, valid_dataset = create_meta_data_gcn (gcn_model, data_ds, embed_class_muv, 12, muv_tasks)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "hidden": true,
    "id": "hn2k_msYf9Rl",
    "outputId": "095e992a-3e82-4eb6-9b57-4ddcf083b2b2",
    "run_control": {
     "marked": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "176337-73549\n"
     ]
    }
   ],
   "source": [
    "print(f'{len(train_dataset)}-{len(valid_dataset)}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "hidden": true,
    "id": "Cuw4bJZZgOoW",
    "outputId": "324218d4-9155-4a08-a4e4-5208e2cfdf9c"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "train positive label: 347 - train negative label: 175990\n",
      "Test positive label: 142 - Test negative label: 73407\n"
     ]
    }
   ],
   "source": [
    "label_pos , label_neg, _ , _  = count_lablel(train_dataset)\n",
    "print(f'train positive label: {label_pos} - train negative label: {label_neg}')\n",
    "\n",
    "label_pos , label_neg, _ , _ = count_lablel(valid_dataset)\n",
    "print(f'Test positive label: {label_pos} - Test negative label: {label_neg}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "hidden": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "up and down sampling => train positive label: 87791 - train negative label: 174230\n"
     ]
    }
   ],
   "source": [
    "train_ds = up_and_down_Samplenig(train_dataset, sacale_upsampling = 2 , scale_downsampling = 0.99)\n",
    "\n",
    "label_pos , label_neg , _ , _ = count_lablel(train_ds)\n",
    "print(f'up and down sampling => train positive label: {label_pos} - train negative label: {label_neg}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true,
    "id": "ZUo6iyu_Hwk4"
   },
   "source": [
    "### Training algorithm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "colab": {
     "background_save": true,
     "base_uri": "https://localhost:8080/"
    },
    "hidden": true,
    "id": "UvKopfaM1yAP",
    "outputId": "b05614c9-0f35-49c8-f53a-142198d775db",
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 22s 11ms/step - loss: 0.6376 - accuracy: 0.6638 - mae: 0.4437 - mse: 0.2226 - auc_8: 0.5379\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 22s 11ms/step - loss: 0.6005 - accuracy: 0.6696 - mae: 0.4144 - mse: 0.2070 - auc_8: 0.6642\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 23s 11ms/step - loss: 0.5875 - accuracy: 0.6924 - mae: 0.4036 - mse: 0.2012 - auc_8: 0.6872\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 29s 14ms/step - loss: 0.5785 - accuracy: 0.7010 - mae: 0.3951 - mse: 0.1973 - auc_8: 0.7003\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 29s 14ms/step - loss: 0.5726 - accuracy: 0.7049 - mae: 0.3904 - mse: 0.1950 - auc_8: 0.7090\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 29s 14ms/step - loss: 0.5680 - accuracy: 0.7076 - mae: 0.3871 - mse: 0.1933 - auc_8: 0.7157\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 28s 14ms/step - loss: 0.5648 - accuracy: 0.7091 - mae: 0.3846 - mse: 0.1922 - auc_8: 0.7198\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 28s 14ms/step - loss: 0.5611 - accuracy: 0.7108 - mae: 0.3821 - mse: 0.1910 - auc_8: 0.7245\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 28s 14ms/step - loss: 0.5581 - accuracy: 0.7126 - mae: 0.3800 - mse: 0.1898 - auc_8: 0.7289\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 28s 14ms/step - loss: 0.5555 - accuracy: 0.7141 - mae: 0.3778 - mse: 0.1887 - auc_8: 0.7327\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 28s 14ms/step - loss: 0.5539 - accuracy: 0.7170 - mae: 0.3764 - mse: 0.1880 - auc_8: 0.7350\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 28s 14ms/step - loss: 0.5558 - accuracy: 0.7160 - mae: 0.3776 - mse: 0.1887 - auc_8: 0.7323\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 23s 11ms/step - loss: 0.5503 - accuracy: 0.7194 - mae: 0.3735 - mse: 0.1865 - auc_8: 0.7400\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 21s 10ms/step - loss: 0.5475 - accuracy: 0.7209 - mae: 0.3714 - mse: 0.1856 - auc_8: 0.7431\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 21s 10ms/step - loss: 0.5449 - accuracy: 0.7207 - mae: 0.3698 - mse: 0.1846 - auc_8: 0.7469\n",
      "72\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "71\n",
      "70\n",
      "70\n",
      "70\n",
      "70\n",
      "69\n",
      "66\n",
      "66\n",
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 22s 11ms/step - loss: 0.5505 - accuracy: 0.7172 - mae: 0.3740 - mse: 0.1869 - auc_8: 0.7389\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 21s 10ms/step - loss: 0.5457 - accuracy: 0.7188 - mae: 0.3707 - mse: 0.1851 - auc_8: 0.7452\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 21s 10ms/step - loss: 0.5426 - accuracy: 0.7197 - mae: 0.3682 - mse: 0.1839 - auc_8: 0.7490\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 22s 11ms/step - loss: 0.5398 - accuracy: 0.7218 - mae: 0.3663 - mse: 0.1829 - auc_8: 0.7527\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 23s 11ms/step - loss: 0.5375 - accuracy: 0.7228 - mae: 0.3644 - mse: 0.1821 - auc_8: 0.7554\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 24s 12ms/step - loss: 0.5339 - accuracy: 0.7244 - mae: 0.3622 - mse: 0.1808 - auc_8: 0.7600\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 24s 12ms/step - loss: 0.5316 - accuracy: 0.7254 - mae: 0.3600 - mse: 0.1799 - auc_8: 0.7628\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 24s 12ms/step - loss: 0.5304 - accuracy: 0.7261 - mae: 0.3593 - mse: 0.1795 - auc_8: 0.7641\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 24s 12ms/step - loss: 0.5326 - accuracy: 0.7248 - mae: 0.3610 - mse: 0.1803 - auc_8: 0.7611\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 24s 12ms/step - loss: 0.5291 - accuracy: 0.7263 - mae: 0.3585 - mse: 0.1792 - auc_8: 0.7649\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 24s 12ms/step - loss: 0.5242 - accuracy: 0.7288 - mae: 0.3550 - mse: 0.1773 - auc_8: 0.7710\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 24s 12ms/step - loss: 0.5239 - accuracy: 0.7288 - mae: 0.3545 - mse: 0.1771 - auc_8: 0.7716\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 24s 12ms/step - loss: 0.5213 - accuracy: 0.7308 - mae: 0.3525 - mse: 0.1762 - auc_8: 0.7744\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 24s 12ms/step - loss: 0.5193 - accuracy: 0.7317 - mae: 0.3512 - mse: 0.1754 - auc_8: 0.7764\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 24s 12ms/step - loss: 0.5177 - accuracy: 0.7320 - mae: 0.3499 - mse: 0.1749 - auc_8: 0.7783\n",
      "73\n",
      "73\n",
      "72\n",
      "72\n",
      "72\n",
      "72\n",
      "72\n",
      "72\n",
      "72\n",
      "72\n",
      "72\n",
      "71\n",
      "71\n",
      "71\n",
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5148 - accuracy: 0.7330 - mae: 0.3480 - mse: 0.1739 - auc_8: 0.7814\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5135 - accuracy: 0.7335 - mae: 0.3469 - mse: 0.1734 - auc_8: 0.7830\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5145 - accuracy: 0.7322 - mae: 0.3476 - mse: 0.1738 - auc_8: 0.7819\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5121 - accuracy: 0.7327 - mae: 0.3461 - mse: 0.1730 - auc_8: 0.7843\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5106 - accuracy: 0.7341 - mae: 0.3446 - mse: 0.1723 - auc_8: 0.7858\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5168 - accuracy: 0.7300 - mae: 0.3494 - mse: 0.1747 - auc_8: 0.7796\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5142 - accuracy: 0.7316 - mae: 0.3476 - mse: 0.1737 - auc_8: 0.7824\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5101 - accuracy: 0.7339 - mae: 0.3444 - mse: 0.1721 - auc_8: 0.7868\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5095 - accuracy: 0.7343 - mae: 0.3442 - mse: 0.1720 - auc_8: 0.7872\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5095 - accuracy: 0.7331 - mae: 0.3438 - mse: 0.1719 - auc_8: 0.7875\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5087 - accuracy: 0.7344 - mae: 0.3432 - mse: 0.1715 - auc_8: 0.7883\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5062 - accuracy: 0.7356 - mae: 0.3416 - mse: 0.1707 - auc_8: 0.7907\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5029 - accuracy: 0.7373 - mae: 0.3392 - mse: 0.1695 - auc_8: 0.7942\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5030 - accuracy: 0.7363 - mae: 0.3392 - mse: 0.1696 - auc_8: 0.7941\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 25s 12ms/step - loss: 0.5010 - accuracy: 0.7383 - mae: 0.3377 - mse: 0.1689 - auc_8: 0.7960\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "73\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "# models = [siamese_net for task in sider_tasks_final]\n",
    "Epoch_S = 15\n",
    "l = []\n",
    "r = []\n",
    "lbls = []\n",
    "for i , data in enumerate(train_ds):\n",
    "    smile, embbed_drug, onehot_task, embbed_task, lbl, task_name = data\n",
    "    l.append(embbed_drug[0])\n",
    "    r.append(embbed_task)\n",
    "    lbls.append(lbl.tolist())\n",
    "\n",
    "l = np.array(l).reshape(-1,128,1)\n",
    "r = np.array(r).reshape(-1,512,1)\n",
    "lbls=np.array(lbls)\n",
    "\n",
    "history = History()\n",
    "\n",
    "siamese_net = siamese_model_attentiveFp_muv()\n",
    "\n",
    "P = siamese_net.fit([l, r], lbls, epochs = Epoch_S, shuffle=True, batch_size=128, callbacks=[history])\n",
    "\n",
    "for j in range(1000):\n",
    "    C=1\n",
    "    Before = int(P.history['accuracy'][-1]*100)\n",
    "    for i in range(2,Epoch_S+1):\n",
    "        if  int(P.history['accuracy'][-i]*100)== Before:\n",
    "            C=C+1\n",
    "        else:\n",
    "            C=1\n",
    "        Before=int(P.history['accuracy'][-i]*100)\n",
    "        print(Before)\n",
    "    if C==Epoch_S:\n",
    "        break\n",
    "    P = siamese_net.fit([l, r], lbls, epochs = Epoch_S, shuffle=True, batch_size=128, callbacks=history)\n",
    "print(j+1)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true,
    "hidden": true,
    "id": "2c_4DEdVIBw4"
   },
   "source": [
    "### Model evaluation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "colab": {
     "background_save": true
    },
    "hidden": true,
    "id": "b-WGsaHvlL8Q"
   },
   "outputs": [],
   "source": [
    "valid_ds = {}\n",
    "\n",
    "for i, task in enumerate(muv_tasks_test):\n",
    "    temp = []\n",
    "    for j , data in enumerate(valid_dataset):\n",
    "        smiles, embbed_drug, onehot_task, embbed_task, lbl, task_name = data\n",
    "        if task ==  task_name:\n",
    "            temp.append(data)\n",
    "    \n",
    "    valid_ds[task] = temp\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "hidden": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MUV-832 : \n",
      "459/459 [==============================] - 1s 2ms/step - loss: 0.3388 - accuracy: 0.8936 - mae: 0.2602 - mse: 0.1011 - auc_8: 0.7056\n",
      "MUV-846 : \n",
      "460/460 [==============================] - 1s 2ms/step - loss: 0.4206 - accuracy: 0.8183 - mae: 0.3091 - mse: 0.1332 - auc_8: 0.7709\n",
      "MUV-852 : \n",
      "458/458 [==============================] - 1s 2ms/step - loss: 0.4146 - accuracy: 0.8176 - mae: 0.3042 - mse: 0.1318 - auc_8: 0.7391\n",
      "MUV-858 : \n",
      "462/462 [==============================] - 1s 2ms/step - loss: 0.3331 - accuracy: 0.9028 - mae: 0.2586 - mse: 0.0979 - auc_8: 0.6079\n",
      "MUV-859 : \n",
      "461/461 [==============================] - 1s 2ms/step - loss: 0.3170 - accuracy: 0.9179 - mae: 0.2455 - mse: 0.0923 - auc_8: 0.4527\n"
     ]
    }
   ],
   "source": [
    "task_scores = [muv_tasks_test for muv_tasks_test in range(len(muv_tasks_test))]\n",
    "\n",
    "for i, task in enumerate(muv_tasks_test):\n",
    "    print(task,\": \")\n",
    "\n",
    "    y_test = []\n",
    "    l_val = []\n",
    "    r_val = []\n",
    "    lbls_valid = []\n",
    "    for data in valid_ds[task]:\n",
    "       \n",
    "        smiles, embbed_drug, onehot_task, embbed_task, lbl, task_name = data\n",
    "        l_val.append(embbed_drug[0])\n",
    "        r_val.append(embbed_task)\n",
    "        lbls_valid.append(lbl)\n",
    "            \n",
    "    l1 = np.asarray(l_val)\n",
    "    r1 = np.asarray(r_val)\n",
    "    lbls_valid = np.asarray(lbls_valid)\n",
    "\n",
    "    score = siamese_net.evaluate([l1,r1],lbls_valid)\n",
    " \n",
    "    result =(score[1], score[4])\n",
    "    task_scores[i] = task,result"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hidden": true,
    "id": "LB42ZdTCyR-N"
   },
   "source": [
    "## Meta-Learning with BioAct-Het and Canonical GCN"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true,
    "hidden": true,
    "id": "KcaEHmQMcFau"
   },
   "source": [
    "### Siamea model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "hidden": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Downloading GCN_canonical_MUV_pre_trained.pth from https://data.dgl.ai/dgllife/pre_trained/gcn_canonical_muv.pth...\n",
      "Pretrained model loaded\n"
     ]
    }
   ],
   "source": [
    "model_GCN = 'GCN_canonical_MUV'\n",
    "gcn_model = get_muv_model(model_GCN)\n",
    "gcn_model.eval()\n",
    "gcn_model = gcn_model.to(device)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "hidden": true,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14841\n",
      "Processing molecule 2000/14841\n",
      "Processing molecule 3000/14841\n",
      "Processing molecule 4000/14841\n",
      "Processing molecule 5000/14841\n",
      "Processing molecule 6000/14841\n",
      "Processing molecule 7000/14841\n",
      "Processing molecule 8000/14841\n",
      "Processing molecule 9000/14841\n",
      "Processing molecule 10000/14841\n",
      "Processing molecule 11000/14841\n",
      "Processing molecule 12000/14841\n",
      "Processing molecule 13000/14841\n",
      "Processing molecule 14000/14841\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14734\n",
      "Processing molecule 2000/14734\n",
      "Processing molecule 3000/14734\n",
      "Processing molecule 4000/14734\n",
      "Processing molecule 5000/14734\n",
      "Processing molecule 6000/14734\n",
      "Processing molecule 7000/14734\n",
      "Processing molecule 8000/14734\n",
      "Processing molecule 9000/14734\n",
      "Processing molecule 10000/14734\n",
      "Processing molecule 11000/14734\n",
      "Processing molecule 12000/14734\n",
      "Processing molecule 13000/14734\n",
      "Processing molecule 14000/14734\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14728\n",
      "Processing molecule 2000/14728\n",
      "Processing molecule 3000/14728\n",
      "Processing molecule 4000/14728\n",
      "Processing molecule 5000/14728\n",
      "Processing molecule 6000/14728\n",
      "Processing molecule 7000/14728\n",
      "Processing molecule 8000/14728\n",
      "Processing molecule 9000/14728\n",
      "Processing molecule 10000/14728\n",
      "Processing molecule 11000/14728\n",
      "Processing molecule 12000/14728\n",
      "Processing molecule 13000/14728\n",
      "Processing molecule 14000/14728\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14623\n",
      "Processing molecule 2000/14623\n",
      "Processing molecule 3000/14623\n",
      "Processing molecule 4000/14623\n",
      "Processing molecule 5000/14623\n",
      "Processing molecule 6000/14623\n",
      "Processing molecule 7000/14623\n",
      "Processing molecule 8000/14623\n",
      "Processing molecule 9000/14623\n",
      "Processing molecule 10000/14623\n",
      "Processing molecule 11000/14623\n",
      "Processing molecule 12000/14623\n",
      "Processing molecule 13000/14623\n",
      "Processing molecule 14000/14623\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14902\n",
      "Processing molecule 2000/14902\n",
      "Processing molecule 3000/14902\n",
      "Processing molecule 4000/14902\n",
      "Processing molecule 5000/14902\n",
      "Processing molecule 6000/14902\n",
      "Processing molecule 7000/14902\n",
      "Processing molecule 8000/14902\n",
      "Processing molecule 9000/14902\n",
      "Processing molecule 10000/14902\n",
      "Processing molecule 11000/14902\n",
      "Processing molecule 12000/14902\n",
      "Processing molecule 13000/14902\n",
      "Processing molecule 14000/14902\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14601\n",
      "Processing molecule 2000/14601\n",
      "Processing molecule 3000/14601\n",
      "Processing molecule 4000/14601\n",
      "Processing molecule 5000/14601\n",
      "Processing molecule 6000/14601\n",
      "Processing molecule 7000/14601\n",
      "Processing molecule 8000/14601\n",
      "Processing molecule 9000/14601\n",
      "Processing molecule 10000/14601\n",
      "Processing molecule 11000/14601\n",
      "Processing molecule 12000/14601\n",
      "Processing molecule 13000/14601\n",
      "Processing molecule 14000/14601\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14644\n",
      "Processing molecule 2000/14644\n",
      "Processing molecule 3000/14644\n",
      "Processing molecule 4000/14644\n",
      "Processing molecule 5000/14644\n",
      "Processing molecule 6000/14644\n",
      "Processing molecule 7000/14644\n",
      "Processing molecule 8000/14644\n",
      "Processing molecule 9000/14644\n",
      "Processing molecule 10000/14644\n",
      "Processing molecule 11000/14644\n",
      "Processing molecule 12000/14644\n",
      "Processing molecule 13000/14644\n",
      "Processing molecule 14000/14644\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14411\n",
      "Processing molecule 2000/14411\n",
      "Processing molecule 3000/14411\n",
      "Processing molecule 4000/14411\n",
      "Processing molecule 5000/14411\n",
      "Processing molecule 6000/14411\n",
      "Processing molecule 7000/14411\n",
      "Processing molecule 8000/14411\n",
      "Processing molecule 9000/14411\n",
      "Processing molecule 10000/14411\n",
      "Processing molecule 11000/14411\n",
      "Processing molecule 12000/14411\n",
      "Processing molecule 13000/14411\n",
      "Processing molecule 14000/14411\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14836\n",
      "Processing molecule 2000/14836\n",
      "Processing molecule 3000/14836\n",
      "Processing molecule 4000/14836\n",
      "Processing molecule 5000/14836\n",
      "Processing molecule 6000/14836\n",
      "Processing molecule 7000/14836\n",
      "Processing molecule 8000/14836\n",
      "Processing molecule 9000/14836\n",
      "Processing molecule 10000/14836\n",
      "Processing molecule 11000/14836\n",
      "Processing molecule 12000/14836\n",
      "Processing molecule 13000/14836\n",
      "Processing molecule 14000/14836\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14682\n",
      "Processing molecule 2000/14682\n",
      "Processing molecule 3000/14682\n",
      "Processing molecule 4000/14682\n",
      "Processing molecule 5000/14682\n",
      "Processing molecule 6000/14682\n",
      "Processing molecule 7000/14682\n",
      "Processing molecule 8000/14682\n",
      "Processing molecule 9000/14682\n",
      "Processing molecule 10000/14682\n",
      "Processing molecule 11000/14682\n",
      "Processing molecule 12000/14682\n",
      "Processing molecule 13000/14682\n",
      "Processing molecule 14000/14682\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14691\n",
      "Processing molecule 2000/14691\n",
      "Processing molecule 3000/14691\n",
      "Processing molecule 4000/14691\n",
      "Processing molecule 5000/14691\n",
      "Processing molecule 6000/14691\n",
      "Processing molecule 7000/14691\n",
      "Processing molecule 8000/14691\n",
      "Processing molecule 9000/14691\n",
      "Processing molecule 10000/14691\n",
      "Processing molecule 11000/14691\n",
      "Processing molecule 12000/14691\n",
      "Processing molecule 13000/14691\n",
      "Processing molecule 14000/14691\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14644\n",
      "Processing molecule 2000/14644\n",
      "Processing molecule 3000/14644\n",
      "Processing molecule 4000/14644\n",
      "Processing molecule 5000/14644\n",
      "Processing molecule 6000/14644\n",
      "Processing molecule 7000/14644\n",
      "Processing molecule 8000/14644\n",
      "Processing molecule 9000/14644\n",
      "Processing molecule 10000/14644\n",
      "Processing molecule 11000/14644\n",
      "Processing molecule 12000/14644\n",
      "Processing molecule 13000/14644\n",
      "Processing molecule 14000/14644\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14667\n",
      "Processing molecule 2000/14667\n",
      "Processing molecule 3000/14667\n",
      "Processing molecule 4000/14667\n",
      "Processing molecule 5000/14667\n",
      "Processing molecule 6000/14667\n",
      "Processing molecule 7000/14667\n",
      "Processing molecule 8000/14667\n",
      "Processing molecule 9000/14667\n",
      "Processing molecule 10000/14667\n",
      "Processing molecule 11000/14667\n",
      "Processing molecule 12000/14667\n",
      "Processing molecule 13000/14667\n",
      "Processing molecule 14000/14667\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14711\n",
      "Processing molecule 2000/14711\n",
      "Processing molecule 3000/14711\n",
      "Processing molecule 4000/14711\n",
      "Processing molecule 5000/14711\n",
      "Processing molecule 6000/14711\n",
      "Processing molecule 7000/14711\n",
      "Processing molecule 8000/14711\n",
      "Processing molecule 9000/14711\n",
      "Processing molecule 10000/14711\n",
      "Processing molecule 11000/14711\n",
      "Processing molecule 12000/14711\n",
      "Processing molecule 13000/14711\n",
      "Processing molecule 14000/14711\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14651\n",
      "Processing molecule 2000/14651\n",
      "Processing molecule 3000/14651\n",
      "Processing molecule 4000/14651\n",
      "Processing molecule 5000/14651\n",
      "Processing molecule 6000/14651\n",
      "Processing molecule 7000/14651\n",
      "Processing molecule 8000/14651\n",
      "Processing molecule 9000/14651\n",
      "Processing molecule 10000/14651\n",
      "Processing molecule 11000/14651\n",
      "Processing molecule 12000/14651\n",
      "Processing molecule 13000/14651\n",
      "Processing molecule 14000/14651\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14774\n",
      "Processing molecule 2000/14774\n",
      "Processing molecule 3000/14774\n",
      "Processing molecule 4000/14774\n",
      "Processing molecule 5000/14774\n",
      "Processing molecule 6000/14774\n",
      "Processing molecule 7000/14774\n",
      "Processing molecule 8000/14774\n",
      "Processing molecule 9000/14774\n",
      "Processing molecule 10000/14774\n",
      "Processing molecule 11000/14774\n",
      "Processing molecule 12000/14774\n",
      "Processing molecule 13000/14774\n",
      "Processing molecule 14000/14774\n",
      "Processing dgl graphs from scratch...\n",
      "Processing molecule 1000/14746\n",
      "Processing molecule 2000/14746\n",
      "Processing molecule 3000/14746\n",
      "Processing molecule 4000/14746\n",
      "Processing molecule 5000/14746\n",
      "Processing molecule 6000/14746\n",
      "Processing molecule 7000/14746\n",
      "Processing molecule 8000/14746\n",
      "Processing molecule 9000/14746\n",
      "Processing molecule 10000/14746\n",
      "Processing molecule 11000/14746\n",
      "Processing molecule 12000/14746\n",
      "Processing molecule 13000/14746\n",
      "Processing molecule 14000/14746\n"
     ]
    }
   ],
   "source": [
    "data_ds = []\n",
    "for i, task in  enumerate(muv_tasks):\n",
    "    a = df[['smiles' , task]]\n",
    "    a = a.dropna()\n",
    "    ds = DATASET(a, smiles_to_bigraph, CanonicalAtomFeaturizer(), cache_file_path = cache_path)\n",
    "    data_ds.append(ds)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "hidden": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Data created!!\n"
     ]
    }
   ],
   "source": [
    "train_dataset, valid_dataset = create_meta_data_gcn (gcn_model, data_ds, embed_class_muv, 12, muv_tasks)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "hidden": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "176337-73549\n"
     ]
    }
   ],
   "source": [
    "print(f'{len(train_dataset)}-{len(valid_dataset)}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "hidden": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "train positive label: 347 - train negative label: 175990\n",
      "Test positive label: 142 - Test negative label: 73407\n"
     ]
    }
   ],
   "source": [
    "label_pos , label_neg, _ , _  = count_lablel(train_dataset)\n",
    "print(f'train positive label: {label_pos} - train negative label: {label_neg}')\n",
    "\n",
    "label_pos , label_neg, _ , _ = count_lablel(valid_dataset)\n",
    "print(f'Test positive label: {label_pos} - Test negative label: {label_neg}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "hidden": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "up and down sampling => train positive label: 87791 - train negative label: 174230\n"
     ]
    }
   ],
   "source": [
    "train_ds = up_and_down_Samplenig(train_dataset, sacale_upsampling = 2 , scale_downsampling = 0.99)\n",
    "\n",
    "label_pos , label_neg , _ , _ = count_lablel(train_ds)\n",
    "print(f'up and down sampling => train positive label: {label_pos} - train negative label: {label_neg}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true,
    "hidden": true,
    "id": "Mi2yDJQVy52B"
   },
   "source": [
    "### Training algorithm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "hidden": true,
    "id": "UWWKNk60y52B",
    "outputId": "1ef42590-8e6c-4af4-964b-7050fc4c4909"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.6156 - accuracy: 0.6699 - mae: 0.4251 - mse: 0.2132 - auc: 0.6240\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.5883 - accuracy: 0.6881 - mae: 0.4052 - mse: 0.2025 - auc: 0.6773\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.5748 - accuracy: 0.6953 - mae: 0.3948 - mse: 0.1971 - auc: 0.7029\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.5632 - accuracy: 0.7044 - mae: 0.3860 - mse: 0.1926 - auc: 0.7206\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.5539 - accuracy: 0.7108 - mae: 0.3790 - mse: 0.1892 - auc: 0.7331\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.5450 - accuracy: 0.7166 - mae: 0.3722 - mse: 0.1858 - auc: 0.7452\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.5400 - accuracy: 0.7203 - mae: 0.3684 - mse: 0.1840 - auc: 0.7513\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.5339 - accuracy: 0.7240 - mae: 0.3640 - mse: 0.1818 - auc: 0.7594\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.5262 - accuracy: 0.7284 - mae: 0.3578 - mse: 0.1788 - auc: 0.7690\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.5192 - accuracy: 0.7322 - mae: 0.3528 - mse: 0.1761 - auc: 0.7781\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.5163 - accuracy: 0.7336 - mae: 0.3501 - mse: 0.1749 - auc: 0.7815\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.5125 - accuracy: 0.7354 - mae: 0.3471 - mse: 0.1734 - auc: 0.7862\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.5040 - accuracy: 0.7410 - mae: 0.3408 - mse: 0.1702 - auc: 0.7954\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.5000 - accuracy: 0.7425 - mae: 0.3378 - mse: 0.1688 - auc: 0.7992\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4946 - accuracy: 0.7471 - mae: 0.3335 - mse: 0.1666 - auc: 0.8049\n",
      "74\n",
      "74\n",
      "73\n",
      "73\n",
      "73\n",
      "72\n",
      "72\n",
      "72\n",
      "71\n",
      "71\n",
      "70\n",
      "69\n",
      "68\n",
      "66\n",
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4899 - accuracy: 0.7491 - mae: 0.3301 - mse: 0.1650 - auc: 0.8092\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4872 - accuracy: 0.7503 - mae: 0.3284 - mse: 0.1641 - auc: 0.8119\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4891 - accuracy: 0.7497 - mae: 0.3295 - mse: 0.1647 - auc: 0.8099\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4900 - accuracy: 0.7471 - mae: 0.3306 - mse: 0.1652 - auc: 0.8087\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4852 - accuracy: 0.7493 - mae: 0.3270 - mse: 0.1635 - auc: 0.8131\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4818 - accuracy: 0.7521 - mae: 0.3247 - mse: 0.1622 - auc: 0.8165\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4793 - accuracy: 0.7530 - mae: 0.3228 - mse: 0.1613 - auc: 0.8186\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4843 - accuracy: 0.7493 - mae: 0.3268 - mse: 0.1633 - auc: 0.8138\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4790 - accuracy: 0.7525 - mae: 0.3228 - mse: 0.1613 - auc: 0.8190\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4768 - accuracy: 0.7536 - mae: 0.3212 - mse: 0.1606 - auc: 0.8207\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4710 - accuracy: 0.7557 - mae: 0.3172 - mse: 0.1585 - auc: 0.8257\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4677 - accuracy: 0.7581 - mae: 0.3151 - mse: 0.1574 - auc: 0.8284\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4654 - accuracy: 0.7590 - mae: 0.3131 - mse: 0.1565 - auc: 0.8305\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4682 - accuracy: 0.7579 - mae: 0.3151 - mse: 0.1574 - auc: 0.8281\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4637 - accuracy: 0.7600 - mae: 0.3119 - mse: 0.1559 - auc: 0.8319\n",
      "75\n",
      "75\n",
      "75\n",
      "75\n",
      "75\n",
      "75\n",
      "74\n",
      "75\n",
      "75\n",
      "74\n",
      "74\n",
      "74\n",
      "75\n",
      "74\n",
      "Epoch 1/15\n",
      "   1/2048 [..............................] - ETA: 0s - loss: 0.5318 - accuracy: 0.7031 - mae: 0.3490 - mse: 0.1879 - auc: 0.7683WARNING:tensorflow:Callbacks method `on_train_batch_begin` is slow compared to the batch time (batch time: 0.0040s vs `on_train_batch_begin` time: 0.0110s). Check your callbacks.\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4613 - accuracy: 0.7621 - mae: 0.3103 - mse: 0.1550 - auc: 0.8341\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4584 - accuracy: 0.7628 - mae: 0.3078 - mse: 0.1539 - auc: 0.8365\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4572 - accuracy: 0.7645 - mae: 0.3070 - mse: 0.1534 - auc: 0.8376\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4515 - accuracy: 0.7670 - mae: 0.3035 - mse: 0.1516 - auc: 0.8417\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4509 - accuracy: 0.7681 - mae: 0.3026 - mse: 0.1513 - auc: 0.8424\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4501 - accuracy: 0.7680 - mae: 0.3022 - mse: 0.1510 - auc: 0.8431\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4489 - accuracy: 0.7692 - mae: 0.3013 - mse: 0.1506 - auc: 0.8439\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4467 - accuracy: 0.7694 - mae: 0.2999 - mse: 0.1499 - auc: 0.8455\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4454 - accuracy: 0.7709 - mae: 0.2988 - mse: 0.1493 - auc: 0.8469\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4438 - accuracy: 0.7706 - mae: 0.2979 - mse: 0.1488 - auc: 0.8479\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4419 - accuracy: 0.7726 - mae: 0.2960 - mse: 0.1480 - auc: 0.8495\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4459 - accuracy: 0.7714 - mae: 0.2989 - mse: 0.1493 - auc: 0.8467\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4391 - accuracy: 0.7751 - mae: 0.2944 - mse: 0.1471 - auc: 0.8517\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4393 - accuracy: 0.7747 - mae: 0.2942 - mse: 0.1471 - auc: 0.8515\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4353 - accuracy: 0.7772 - mae: 0.2914 - mse: 0.1456 - auc: 0.8546\n",
      "77\n",
      "77\n",
      "77\n",
      "77\n",
      "77\n",
      "77\n",
      "76\n",
      "76\n",
      "76\n",
      "76\n",
      "76\n",
      "76\n",
      "76\n",
      "76\n",
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4361 - accuracy: 0.7771 - mae: 0.2920 - mse: 0.1460 - auc: 0.8539\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4348 - accuracy: 0.7777 - mae: 0.2909 - mse: 0.1455 - auc: 0.8550\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4328 - accuracy: 0.7793 - mae: 0.2897 - mse: 0.1447 - auc: 0.8565\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4315 - accuracy: 0.7787 - mae: 0.2888 - mse: 0.1443 - auc: 0.8574\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4324 - accuracy: 0.7785 - mae: 0.2895 - mse: 0.1446 - auc: 0.8567\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4274 - accuracy: 0.7840 - mae: 0.2851 - mse: 0.1425 - auc: 0.8611\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4350 - accuracy: 0.7781 - mae: 0.2907 - mse: 0.1454 - auc: 0.8550\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4293 - accuracy: 0.7811 - mae: 0.2870 - mse: 0.1434 - auc: 0.8593\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4276 - accuracy: 0.7833 - mae: 0.2855 - mse: 0.1427 - auc: 0.8608\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4307 - accuracy: 0.7802 - mae: 0.2878 - mse: 0.1438 - auc: 0.8583\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4278 - accuracy: 0.7824 - mae: 0.2857 - mse: 0.1428 - auc: 0.8605\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4270 - accuracy: 0.7832 - mae: 0.2854 - mse: 0.1426 - auc: 0.8610\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4242 - accuracy: 0.7849 - mae: 0.2829 - mse: 0.1414 - auc: 0.8633\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4231 - accuracy: 0.7858 - mae: 0.2824 - mse: 0.1410 - auc: 0.8641\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4226 - accuracy: 0.7855 - mae: 0.2818 - mse: 0.1409 - auc: 0.8644\n",
      "78\n",
      "78\n",
      "78\n",
      "78\n",
      "78\n",
      "78\n",
      "78\n",
      "77\n",
      "78\n",
      "77\n",
      "77\n",
      "77\n",
      "77\n",
      "77\n",
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4208 - accuracy: 0.7867 - mae: 0.2806 - mse: 0.1402 - auc: 0.8656\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4188 - accuracy: 0.7877 - mae: 0.2789 - mse: 0.1394 - auc: 0.8673\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4211 - accuracy: 0.7868 - mae: 0.2804 - mse: 0.1402 - auc: 0.8656\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4174 - accuracy: 0.7898 - mae: 0.2780 - mse: 0.1389 - auc: 0.8683\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4180 - accuracy: 0.7900 - mae: 0.2778 - mse: 0.1389 - auc: 0.8682\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4184 - accuracy: 0.7888 - mae: 0.2785 - mse: 0.1392 - auc: 0.8676\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4187 - accuracy: 0.7890 - mae: 0.2790 - mse: 0.1395 - auc: 0.8671\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4133 - accuracy: 0.7917 - mae: 0.2748 - mse: 0.1374 - auc: 0.8713\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4138 - accuracy: 0.7912 - mae: 0.2755 - mse: 0.1378 - auc: 0.8704\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4217 - accuracy: 0.7863 - mae: 0.2814 - mse: 0.1406 - auc: 0.8650\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4185 - accuracy: 0.7884 - mae: 0.2790 - mse: 0.1395 - auc: 0.8672\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4191 - accuracy: 0.7880 - mae: 0.2794 - mse: 0.1396 - auc: 0.8671\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4182 - accuracy: 0.7875 - mae: 0.2788 - mse: 0.1394 - auc: 0.8673\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4153 - accuracy: 0.7907 - mae: 0.2764 - mse: 0.1382 - auc: 0.8697\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4172 - accuracy: 0.7899 - mae: 0.2777 - mse: 0.1388 - auc: 0.8685\n",
      "79\n",
      "78\n",
      "78\n",
      "78\n",
      "78\n",
      "79\n",
      "79\n",
      "78\n",
      "78\n",
      "79\n",
      "78\n",
      "78\n",
      "78\n",
      "78\n",
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4155 - accuracy: 0.7897 - mae: 0.2767 - mse: 0.1384 - auc: 0.8693\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4140 - accuracy: 0.7906 - mae: 0.2759 - mse: 0.1379 - auc: 0.8702\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4137 - accuracy: 0.7913 - mae: 0.2754 - mse: 0.1376 - auc: 0.8708\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4117 - accuracy: 0.7924 - mae: 0.2742 - mse: 0.1370 - auc: 0.8719\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4127 - accuracy: 0.7916 - mae: 0.2747 - mse: 0.1374 - auc: 0.8713\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4101 - accuracy: 0.7936 - mae: 0.2727 - mse: 0.1364 - auc: 0.8733\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4081 - accuracy: 0.7945 - mae: 0.2712 - mse: 0.1356 - auc: 0.8746\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4105 - accuracy: 0.7936 - mae: 0.2726 - mse: 0.1363 - auc: 0.8733\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4080 - accuracy: 0.7948 - mae: 0.2713 - mse: 0.1356 - auc: 0.8747\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4097 - accuracy: 0.7926 - mae: 0.2729 - mse: 0.1363 - auc: 0.8731\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4081 - accuracy: 0.7955 - mae: 0.2709 - mse: 0.1355 - auc: 0.8748\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4159 - accuracy: 0.7894 - mae: 0.2769 - mse: 0.1384 - auc: 0.8693\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4141 - accuracy: 0.7900 - mae: 0.2758 - mse: 0.1379 - auc: 0.8703\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4104 - accuracy: 0.7930 - mae: 0.2732 - mse: 0.1364 - auc: 0.8731\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4103 - accuracy: 0.7931 - mae: 0.2724 - mse: 0.1362 - auc: 0.8733\n",
      "79\n",
      "78\n",
      "78\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "78\n",
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4077 - accuracy: 0.7955 - mae: 0.2708 - mse: 0.1353 - auc: 0.8750\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4065 - accuracy: 0.7953 - mae: 0.2704 - mse: 0.1352 - auc: 0.8755\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4084 - accuracy: 0.7944 - mae: 0.2713 - mse: 0.1356 - auc: 0.8744\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4066 - accuracy: 0.7951 - mae: 0.2702 - mse: 0.1351 - auc: 0.8756\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4069 - accuracy: 0.7949 - mae: 0.2705 - mse: 0.1353 - auc: 0.8752\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4044 - accuracy: 0.7974 - mae: 0.2683 - mse: 0.1341 - auc: 0.8774\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4024 - accuracy: 0.7986 - mae: 0.2670 - mse: 0.1335 - auc: 0.8785\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4076 - accuracy: 0.7942 - mae: 0.2708 - mse: 0.1354 - auc: 0.8749\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4063 - accuracy: 0.7959 - mae: 0.2699 - mse: 0.1349 - auc: 0.8759\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4033 - accuracy: 0.7976 - mae: 0.2679 - mse: 0.1338 - auc: 0.8779\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4012 - accuracy: 0.7979 - mae: 0.2661 - mse: 0.1332 - auc: 0.8790\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4013 - accuracy: 0.7985 - mae: 0.2659 - mse: 0.1330 - auc: 0.8793\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.4027 - accuracy: 0.7979 - mae: 0.2671 - mse: 0.1335 - auc: 0.8785\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.3997 - accuracy: 0.8001 - mae: 0.2649 - mse: 0.1325 - auc: 0.8803\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4049 - accuracy: 0.7974 - mae: 0.2686 - mse: 0.1343 - auc: 0.8771\n",
      "80\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "79\n",
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.3994 - accuracy: 0.7997 - mae: 0.2650 - mse: 0.1324 - auc: 0.8805\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3991 - accuracy: 0.8010 - mae: 0.2643 - mse: 0.1321 - auc: 0.8810\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3990 - accuracy: 0.8004 - mae: 0.2645 - mse: 0.1322 - auc: 0.8807\n",
      "Epoch 4/15\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3977 - accuracy: 0.8010 - mae: 0.2636 - mse: 0.1319 - auc: 0.8815\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3982 - accuracy: 0.8003 - mae: 0.2640 - mse: 0.1319 - auc: 0.8813\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.3952 - accuracy: 0.8031 - mae: 0.2617 - mse: 0.1308 - auc: 0.8835\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.4017 - accuracy: 0.7988 - mae: 0.2657 - mse: 0.1330 - auc: 0.8794\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3992 - accuracy: 0.8001 - mae: 0.2644 - mse: 0.1322 - auc: 0.8809\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3981 - accuracy: 0.8010 - mae: 0.2638 - mse: 0.1318 - auc: 0.8815\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3954 - accuracy: 0.8018 - mae: 0.2618 - mse: 0.1308 - auc: 0.8833\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3948 - accuracy: 0.8025 - mae: 0.2614 - mse: 0.1307 - auc: 0.8835\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 8s 4ms/step - loss: 0.3945 - accuracy: 0.8027 - mae: 0.2610 - mse: 0.1305 - auc: 0.8838\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3949 - accuracy: 0.8022 - mae: 0.2617 - mse: 0.1308 - auc: 0.8834\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3943 - accuracy: 0.8038 - mae: 0.2607 - mse: 0.1304 - auc: 0.8840\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3999 - accuracy: 0.7997 - mae: 0.2648 - mse: 0.1323 - auc: 0.8805\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "79\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "79\n",
      "Epoch 1/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3905 - accuracy: 0.8049 - mae: 0.2585 - mse: 0.1291 - auc: 0.8865\n",
      "Epoch 2/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3950 - accuracy: 0.8028 - mae: 0.2613 - mse: 0.1306 - auc: 0.8837\n",
      "Epoch 3/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3887 - accuracy: 0.8062 - mae: 0.2567 - mse: 0.1284 - auc: 0.8875\n",
      "Epoch 4/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3887 - accuracy: 0.8065 - mae: 0.2567 - mse: 0.1283 - auc: 0.8877\n",
      "Epoch 5/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3895 - accuracy: 0.8054 - mae: 0.2575 - mse: 0.1288 - auc: 0.8870\n",
      "Epoch 6/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3901 - accuracy: 0.8055 - mae: 0.2576 - mse: 0.1288 - auc: 0.8869\n",
      "Epoch 7/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3898 - accuracy: 0.8062 - mae: 0.2574 - mse: 0.1287 - auc: 0.8870\n",
      "Epoch 8/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3881 - accuracy: 0.8065 - mae: 0.2565 - mse: 0.1282 - auc: 0.8880\n",
      "Epoch 9/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3906 - accuracy: 0.8053 - mae: 0.2580 - mse: 0.1289 - auc: 0.8866\n",
      "Epoch 10/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3892 - accuracy: 0.8071 - mae: 0.2567 - mse: 0.1284 - auc: 0.8875\n",
      "Epoch 11/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3869 - accuracy: 0.8079 - mae: 0.2554 - mse: 0.1277 - auc: 0.8889\n",
      "Epoch 12/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3845 - accuracy: 0.8087 - mae: 0.2535 - mse: 0.1269 - auc: 0.8903\n",
      "Epoch 13/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3879 - accuracy: 0.8076 - mae: 0.2562 - mse: 0.1280 - auc: 0.8882\n",
      "Epoch 14/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3872 - accuracy: 0.8073 - mae: 0.2556 - mse: 0.1278 - auc: 0.8886\n",
      "Epoch 15/15\n",
      "2048/2048 [==============================] - 7s 4ms/step - loss: 0.3861 - accuracy: 0.8071 - mae: 0.2552 - mse: 0.1276 - auc: 0.8892\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "80\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "# models = [siamese_net for task in sider_tasks_final]\n",
    "Epoch_S = 15\n",
    "l = []\n",
    "r = []\n",
    "lbls = []\n",
    "for i , data in enumerate(train_ds):\n",
    "    smile, embbed_drug, onehot_task, embbed_task, lbl, task_name = data\n",
    "    l.append(embbed_drug[0])\n",
    "    r.append(embbed_task)\n",
    "    lbls.append(lbl.tolist())\n",
    "\n",
    "l = np.array(l).reshape(-1,128,1)\n",
    "r = np.array(r).reshape(-1,512,1)\n",
    "lbls=np.array(lbls)\n",
    "\n",
    "history = History()\n",
    "\n",
    "siamese_net = siamese_model_Canonical_muv()\n",
    "\n",
    "P = siamese_net.fit([l, r], lbls, epochs = Epoch_S, shuffle=True, batch_size=128, callbacks=[history])\n",
    "\n",
    "for j in range(1000):\n",
    "    C=1\n",
    "    Before = int(P.history['accuracy'][-1]*100)\n",
    "    for i in range(2,Epoch_S+1):\n",
    "        if  int(P.history['accuracy'][-i]*100)== Before:\n",
    "            C=C+1\n",
    "        else:\n",
    "            C=1\n",
    "        Before=int(P.history['accuracy'][-i]*100)\n",
    "        print(Before)\n",
    "    if C==Epoch_S:\n",
    "        break\n",
    "    P = siamese_net.fit([l, r], lbls, epochs = Epoch_S, shuffle=True, batch_size=128, callbacks=history)\n",
    "print(j+1)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": true,
    "hidden": true,
    "id": "QVF4gne7y52D"
   },
   "source": [
    "### Model evaluation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "hidden": true,
    "id": "vOrTcoNLy52F"
   },
   "outputs": [],
   "source": [
    "valid_ds = {}\n",
    "\n",
    "for i, task in enumerate(muv_tasks_test):\n",
    "    temp = []\n",
    "    for j , data in enumerate(valid_dataset):\n",
    "        smiles, embbed_drug, onehot_task, embbed_task, lbl, task_name = data\n",
    "        if task ==  task_name:\n",
    "            temp.append(data)\n",
    "    \n",
    "    valid_ds[task] = temp\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "hidden": true,
    "id": "ZjQ0tZSJy52G",
    "outputId": "134a0ef5-bcb8-466e-ed15-7d508bf4faf6"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MUV-832 : \n",
      "459/459 [==============================] - 0s 613us/step - loss: 0.2207 - accuracy: 0.8973 - mae: 0.1614 - mse: 0.0692 - auc: 0.6220\n",
      "MUV-846 : \n",
      "460/460 [==============================] - 0s 601us/step - loss: 0.2448 - accuracy: 0.8749 - mae: 0.1776 - mse: 0.0789 - auc: 0.7106\n",
      "MUV-852 : \n",
      "458/458 [==============================] - 0s 594us/step - loss: 0.2494 - accuracy: 0.8743 - mae: 0.1807 - mse: 0.0801 - auc: 0.6196\n",
      "MUV-858 : \n",
      "462/462 [==============================] - 0s 596us/step - loss: 0.2137 - accuracy: 0.9029 - mae: 0.1566 - mse: 0.0660 - auc: 0.6450\n",
      "MUV-859 : \n",
      "461/461 [==============================] - 0s 593us/step - loss: 0.2095 - accuracy: 0.9080 - mae: 0.1518 - mse: 0.0641 - auc: 0.4993\n"
     ]
    }
   ],
   "source": [
    "task_scores = [muv_tasks_test for muv_tasks_test in range(len(muv_tasks_test))]\n",
    "\n",
    "for i, task in enumerate(muv_tasks_test):\n",
    "    print(task,\": \")\n",
    "\n",
    "    y_test = []\n",
    "    l_val = []\n",
    "    r_val = []\n",
    "    lbls_valid = []\n",
    "    for data in valid_ds[task]:\n",
    "       \n",
    "        smiles, embbed_drug, onehot_task, embbed_task, lbl, task_name = data\n",
    "        l_val.append(embbed_drug[0])\n",
    "        r_val.append(embbed_task)\n",
    "        lbls_valid.append(lbl)\n",
    "            \n",
    "    l1 = np.asarray(l_val)\n",
    "    r1 = np.asarray(r_val)\n",
    "    lbls_valid = np.asarray(lbls_valid)\n",
    "\n",
    "    score = siamese_net.evaluate([l1,r1],lbls_valid)\n",
    " \n",
    "    result =(score[1], score[4])\n",
    "    task_scores[i] = task,result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hidden": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [
    "2c_4DEdVIBw4",
    "TqRcDqfVg1-u",
    "4sXOF78fi_l1",
    "qgEyQDvTR0dc",
    "JYgeHvfDR_G-",
    "LQNN1GRCiSpw",
    "JlhliyMkZLny",
    "G2xxKRnXk_bT",
    "PcFWBaEMSFB7",
    "VoOtM-2vik1P",
    "Ub4lZM_hjD42",
    "0dj6NCbDx6KH",
    "0fI1XZ0bSKR-",
    "sib1-l7xivgX",
    "NqdDDrG9jG2X",
    "Zmg-EGEczLAr",
    "X6Df06l0i7r2",
    "ZPVtZ1ZejLDU",
    "Gha2SSiZzQpP",
    "LB42ZdTCyR-N",
    "KcaEHmQMcFau",
    "Mi2yDJQVy52B",
    "QVF4gne7y52D",
    "u8rUwI6DGHfr",
    "g7JX0liYGHfu",
    "ScVDqpneGHf3",
    "c5oS9piaGHf7",
    "wUV7a4ZXGHf9",
    "vuvzISEVGHf-",
    "y5y2ITukGHf_",
    "rUaD5zAqOzPP"
   ],
   "provenance": []
  },
  "gpuClass": "standard",
  "hide_input": false,
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.16"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
